blob: 62087fb4208dd41a6e318a3d6ccdf07ade4c76bb [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\
97\n\
Victor Stinner95e2cbf2019-03-01 16:25:19 +010098--check-hash-based-pycs always|default|never:\n\
99 control how Python invalidates hash-based .pyc files\n\
100";
101static const char usage_4[] = "\
102file : program read from script file\n\
103- : program read from stdin (default; interactive mode if a tty)\n\
104arg ...: arguments passed to program in sys.argv[1:]\n\n\
105Other environment variables:\n\
106PYTHONSTARTUP: file executed on interactive startup (no default)\n\
107PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
108 default module search path. The result is sys.path.\n\
109";
110static const char usage_5[] =
111"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
112" The default module search path uses %s.\n"
Sandro Mani8f023a22020-06-08 17:28:11 +0200113"PYTHONPLATLIBDIR : override sys.platlibdir.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100114"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
Inada Naoki95826c72019-12-14 14:27:32 +0900115"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100116"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
117"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
118static const char usage_6[] =
119"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Serhiy Storchakae9c90aa2019-08-24 12:49:27 +0300120" to seed the hashes of str and bytes objects. It can also be set to an\n"
121" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100122" predictable seed.\n"
123"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
124" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
125" hooks.\n"
126"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
127" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
128" locale coercion and locale compatibility warnings on stderr.\n"
129"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
130" debugger. It can be set to the callable of your debugger of choice.\n"
131"PYTHONDEVMODE: enable the development mode.\n"
132"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
133
134#if defined(MS_WINDOWS)
135# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
136#else
137# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
138#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200139
140
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100141/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200142
Victor Stinner6c785c02018-08-01 17:56:14 +0200143/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200144 stdin and stdout error handler to "surrogateescape". */
145int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200146int Py_DebugFlag = 0; /* Needed by parser.c */
147int Py_VerboseFlag = 0; /* Needed by import.c */
148int Py_QuietFlag = 0; /* Needed by sysmodule.c */
149int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
150int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
151int Py_OptimizeFlag = 0; /* Needed by compile.c */
152int Py_NoSiteFlag = 0; /* Suppress 'import site' */
153int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
154int Py_FrozenFlag = 0; /* Needed by getpath.c */
155int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
156int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
157int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
158int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
159int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
160int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
161#ifdef MS_WINDOWS
162int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
163int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
164#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200165
166
Victor Stinner1075d162019-03-25 23:19:57 +0100167static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100168_Py_GetGlobalVariablesAsDict(void)
169{
170 PyObject *dict, *obj;
171
172 dict = PyDict_New();
173 if (dict == NULL) {
174 return NULL;
175 }
176
177#define SET_ITEM(KEY, EXPR) \
178 do { \
179 obj = (EXPR); \
180 if (obj == NULL) { \
181 return NULL; \
182 } \
183 int res = PyDict_SetItemString(dict, (KEY), obj); \
184 Py_DECREF(obj); \
185 if (res < 0) { \
186 goto fail; \
187 } \
188 } while (0)
189#define SET_ITEM_INT(VAR) \
190 SET_ITEM(#VAR, PyLong_FromLong(VAR))
191#define FROM_STRING(STR) \
192 ((STR != NULL) ? \
193 PyUnicode_FromString(STR) \
194 : (Py_INCREF(Py_None), Py_None))
195#define SET_ITEM_STR(VAR) \
196 SET_ITEM(#VAR, FROM_STRING(VAR))
197
198 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
199 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
200 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
201 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
202
203 SET_ITEM_INT(Py_UTF8Mode);
204 SET_ITEM_INT(Py_DebugFlag);
205 SET_ITEM_INT(Py_VerboseFlag);
206 SET_ITEM_INT(Py_QuietFlag);
207 SET_ITEM_INT(Py_InteractiveFlag);
208 SET_ITEM_INT(Py_InspectFlag);
209
210 SET_ITEM_INT(Py_OptimizeFlag);
211 SET_ITEM_INT(Py_NoSiteFlag);
212 SET_ITEM_INT(Py_BytesWarningFlag);
213 SET_ITEM_INT(Py_FrozenFlag);
214 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
215 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
216 SET_ITEM_INT(Py_NoUserSiteDirectory);
217 SET_ITEM_INT(Py_UnbufferedStdioFlag);
218 SET_ITEM_INT(Py_HashRandomizationFlag);
219 SET_ITEM_INT(Py_IsolatedFlag);
220
221#ifdef MS_WINDOWS
222 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
223 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
224#endif
225
226 return dict;
227
228fail:
229 Py_DECREF(dict);
230 return NULL;
231
232#undef FROM_STRING
233#undef SET_ITEM
234#undef SET_ITEM_INT
235#undef SET_ITEM_STR
236}
237
238
Victor Stinner331a6a52019-05-27 16:39:22 +0200239/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200240
Victor Stinner331a6a52019-05-27 16:39:22 +0200241PyStatus PyStatus_Ok(void)
242{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200243
Victor Stinner331a6a52019-05-27 16:39:22 +0200244PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200245{
Victor Stinner048a3562020-11-05 00:45:56 +0100246 assert(err_msg != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +0200247 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner048a3562020-11-05 00:45:56 +0100248 .err_msg = err_msg};
Victor Stinner871ff772019-05-17 23:54:00 +0200249}
250
Victor Stinner331a6a52019-05-27 16:39:22 +0200251PyStatus PyStatus_NoMemory(void)
252{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200253
Victor Stinner331a6a52019-05-27 16:39:22 +0200254PyStatus PyStatus_Exit(int exitcode)
255{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200256
257
Victor Stinner331a6a52019-05-27 16:39:22 +0200258int PyStatus_IsError(PyStatus status)
259{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200260
Victor Stinner331a6a52019-05-27 16:39:22 +0200261int PyStatus_IsExit(PyStatus status)
262{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200263
Victor Stinner331a6a52019-05-27 16:39:22 +0200264int PyStatus_Exception(PyStatus status)
265{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200266
Victor Stinner048a3562020-11-05 00:45:56 +0100267PyObject*
268_PyErr_SetFromPyStatus(PyStatus status)
269{
270 if (!_PyStatus_IS_ERROR(status)) {
271 PyErr_Format(PyExc_SystemError,
272 "%s() expects an error PyStatus",
273 _PyStatus_GET_FUNC());
274 }
275 else if (status.func) {
276 PyErr_Format(PyExc_ValueError, "%s: %s", status.func, status.err_msg);
277 }
278 else {
279 PyErr_Format(PyExc_ValueError, "%s", status.err_msg);
280 }
281 return NULL;
282}
283
Victor Stinner871ff772019-05-17 23:54:00 +0200284
Victor Stinner331a6a52019-05-27 16:39:22 +0200285/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100286
287#ifndef NDEBUG
288int
Victor Stinner331a6a52019-05-27 16:39:22 +0200289_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100290{
291 assert(list->length >= 0);
292 if (list->length != 0) {
293 assert(list->items != NULL);
294 }
295 for (Py_ssize_t i = 0; i < list->length; i++) {
296 assert(list->items[i] != NULL);
297 }
298 return 1;
299}
300#endif /* Py_DEBUG */
301
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100302
Victor Stinner6c785c02018-08-01 17:56:14 +0200303void
Victor Stinner331a6a52019-05-27 16:39:22 +0200304_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200305{
Victor Stinner331a6a52019-05-27 16:39:22 +0200306 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100307 for (Py_ssize_t i=0; i < list->length; i++) {
308 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200309 }
Victor Stinner74f65682019-03-15 15:08:05 +0100310 PyMem_RawFree(list->items);
311 list->length = 0;
312 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200313}
314
315
Victor Stinner74f65682019-03-15 15:08:05 +0100316int
Victor Stinner331a6a52019-05-27 16:39:22 +0200317_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200318{
Victor Stinner331a6a52019-05-27 16:39:22 +0200319 assert(_PyWideStringList_CheckConsistency(list));
320 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100321
322 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200323 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100324 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300325 }
Victor Stinner74f65682019-03-15 15:08:05 +0100326
Victor Stinnerfb4ae152019-09-30 01:40:17 +0200327 PyWideStringList copy = _PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100328
329 size_t size = list2->length * sizeof(list2->items[0]);
330 copy.items = PyMem_RawMalloc(size);
331 if (copy.items == NULL) {
332 return -1;
333 }
334
335 for (Py_ssize_t i=0; i < list2->length; i++) {
336 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
337 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200338 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100339 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200340 }
Victor Stinner74f65682019-03-15 15:08:05 +0100341 copy.items[i] = item;
342 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200343 }
Victor Stinner74f65682019-03-15 15:08:05 +0100344
Victor Stinner331a6a52019-05-27 16:39:22 +0200345 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100346 *list = copy;
347 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200348}
349
350
Victor Stinner331a6a52019-05-27 16:39:22 +0200351PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100352PyWideStringList_Insert(PyWideStringList *list,
353 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100354{
Victor Stinner3842f292019-08-23 16:57:54 +0100355 Py_ssize_t len = list->length;
356 if (len == PY_SSIZE_T_MAX) {
Min ho Kim96e12d52019-07-22 06:12:33 +1000357 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200358 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100359 }
Victor Stinner3842f292019-08-23 16:57:54 +0100360 if (index < 0) {
361 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
362 }
363 if (index > len) {
364 index = len;
365 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100366
Victor Stinner74f65682019-03-15 15:08:05 +0100367 wchar_t *item2 = _PyMem_RawWcsdup(item);
368 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200369 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100370 }
Victor Stinner74f65682019-03-15 15:08:05 +0100371
Victor Stinner3842f292019-08-23 16:57:54 +0100372 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100373 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
374 if (items2 == NULL) {
375 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200376 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100377 }
378
Victor Stinner3842f292019-08-23 16:57:54 +0100379 if (index < len) {
380 memmove(&items2[index + 1],
381 &items2[index],
382 (len - index) * sizeof(items2[0]));
383 }
384
385 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100386 list->items = items2;
387 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200388 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100389}
390
391
Victor Stinner331a6a52019-05-27 16:39:22 +0200392PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100393PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
394{
395 return PyWideStringList_Insert(list, list->length, item);
396}
397
398
399PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200400_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100401{
402 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200403 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
404 if (_PyStatus_EXCEPTION(status)) {
405 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100406 }
407 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200408 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100409}
410
411
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100412static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200413_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100414{
415 for (Py_ssize_t i = 0; i < list->length; i++) {
416 if (wcscmp(list->items[i], item) == 0) {
417 return 1;
418 }
419 }
420 return 0;
421}
422
423
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100424PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200425_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100426{
Victor Stinner331a6a52019-05-27 16:39:22 +0200427 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100428
Victor Stinner74f65682019-03-15 15:08:05 +0100429 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100430 if (pylist == NULL) {
431 return NULL;
432 }
433
Victor Stinner74f65682019-03-15 15:08:05 +0100434 for (Py_ssize_t i = 0; i < list->length; i++) {
435 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
436 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100437 Py_DECREF(pylist);
438 return NULL;
439 }
Victor Stinner74f65682019-03-15 15:08:05 +0100440 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100441 }
442 return pylist;
443}
444
445
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100446/* --- Py_SetStandardStreamEncoding() ----------------------------- */
447
Victor Stinner124b9eb2018-08-29 01:29:06 +0200448/* Helper to allow an embedding application to override the normal
449 * mechanism that attempts to figure out an appropriate IO encoding
450 */
451
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200452static char *_Py_StandardStreamEncoding = NULL;
453static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200454
455int
456Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
457{
458 if (Py_IsInitialized()) {
459 /* This is too late to have any effect */
460 return -1;
461 }
462
463 int res = 0;
464
465 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
466 but Py_Initialize() can change the allocator. Use a known allocator
467 to be able to release the memory later. */
468 PyMemAllocatorEx old_alloc;
469 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
470
471 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
472 * initialised yet.
473 *
474 * However, the raw memory allocators are initialised appropriately
475 * as C static variables, so _PyMem_RawStrdup is OK even though
476 * Py_Initialize hasn't been called yet.
477 */
478 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200479 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200480 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
481 if (!_Py_StandardStreamEncoding) {
482 res = -2;
483 goto done;
484 }
485 }
486 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200487 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200488 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
489 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200490 PyMem_RawFree(_Py_StandardStreamEncoding);
491 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200492 res = -3;
493 goto done;
494 }
495 }
496#ifdef MS_WINDOWS
497 if (_Py_StandardStreamEncoding) {
498 /* Overriding the stream encoding implies legacy streams */
499 Py_LegacyWindowsStdioFlag = 1;
500 }
501#endif
502
503done:
504 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
505
506 return res;
507}
508
509
510void
511_Py_ClearStandardStreamEncoding(void)
512{
513 /* Use the same allocator than Py_SetStandardStreamEncoding() */
514 PyMemAllocatorEx old_alloc;
515 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
516
517 /* We won't need them anymore. */
518 if (_Py_StandardStreamEncoding) {
519 PyMem_RawFree(_Py_StandardStreamEncoding);
520 _Py_StandardStreamEncoding = NULL;
521 }
522 if (_Py_StandardStreamErrors) {
523 PyMem_RawFree(_Py_StandardStreamErrors);
524 _Py_StandardStreamErrors = NULL;
525 }
526
527 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
528}
529
530
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100531/* --- Py_GetArgcArgv() ------------------------------------------- */
532
533/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200534static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100535
536
537void
538_Py_ClearArgcArgv(void)
539{
540 PyMemAllocatorEx old_alloc;
541 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
542
Victor Stinner331a6a52019-05-27 16:39:22 +0200543 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100544
545 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
546}
547
548
Victor Stinner4fffd382019-03-06 01:44:31 +0100549static int
Victor Stinner74f65682019-03-15 15:08:05 +0100550_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100551{
Victor Stinner331a6a52019-05-27 16:39:22 +0200552 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100553 int res;
554
555 PyMemAllocatorEx old_alloc;
556 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
557
Victor Stinner331a6a52019-05-27 16:39:22 +0200558 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100559
560 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
561 return res;
562}
563
564
Victor Stinner4b9aad42020-11-02 16:49:54 +0100565// _PyConfig_Write() calls _Py_SetArgcArgv() with PyConfig.orig_argv.
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100566void
567Py_GetArgcArgv(int *argc, wchar_t ***argv)
568{
Victor Stinner74f65682019-03-15 15:08:05 +0100569 *argc = (int)orig_argv.length;
570 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100571}
572
573
Victor Stinner331a6a52019-05-27 16:39:22 +0200574/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100575
576#define DECODE_LOCALE_ERR(NAME, LEN) \
577 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200578 ? _PyStatus_ERR("cannot decode " NAME) \
579 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100580
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100581#define MAX_HASH_SEED 4294967295UL
582
583
584#ifndef NDEBUG
585static int
586config_check_consistency(const PyConfig *config)
587{
588 /* Check config consistency */
589 assert(config->isolated >= 0);
590 assert(config->use_environment >= 0);
591 assert(config->dev_mode >= 0);
592 assert(config->install_signal_handlers >= 0);
593 assert(config->use_hash_seed >= 0);
594 assert(config->hash_seed <= MAX_HASH_SEED);
595 assert(config->faulthandler >= 0);
596 assert(config->tracemalloc >= 0);
597 assert(config->import_time >= 0);
598 assert(config->show_ref_count >= 0);
599 assert(config->dump_refs >= 0);
600 assert(config->malloc_stats >= 0);
601 assert(config->site_import >= 0);
602 assert(config->bytes_warning >= 0);
603 assert(config->inspect >= 0);
604 assert(config->interactive >= 0);
605 assert(config->optimization_level >= 0);
606 assert(config->parser_debug >= 0);
607 assert(config->write_bytecode >= 0);
608 assert(config->verbose >= 0);
609 assert(config->quiet >= 0);
610 assert(config->user_site_directory >= 0);
611 assert(config->parse_argv >= 0);
612 assert(config->configure_c_stdio >= 0);
613 assert(config->buffered_stdio >= 0);
614 assert(config->program_name != NULL);
615 assert(_PyWideStringList_CheckConsistency(&config->orig_argv));
616 assert(_PyWideStringList_CheckConsistency(&config->argv));
617 /* sys.argv must be non-empty: empty argv is replaced with [''] */
618 assert(config->argv.length >= 1);
619 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
620 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
621 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
622 assert(config->module_search_paths_set >= 0);
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100623 assert(config->platlibdir != NULL);
624 assert(config->filesystem_encoding != NULL);
625 assert(config->filesystem_errors != NULL);
626 assert(config->stdio_encoding != NULL);
627 assert(config->stdio_errors != NULL);
628#ifdef MS_WINDOWS
629 assert(config->legacy_windows_stdio >= 0);
630#endif
631 /* -c and -m options are exclusive */
632 assert(!(config->run_command != NULL && config->run_module != NULL));
633 assert(config->check_hash_pycs_mode != NULL);
634 assert(config->_install_importlib >= 0);
635 assert(config->pathconfig_warnings >= 0);
636 return 1;
637}
638#endif
639
Victor Stinner441b10c2019-09-28 04:28:35 +0200640
Victor Stinner6c785c02018-08-01 17:56:14 +0200641/* Free memory allocated in config, but don't clear all attributes */
642void
Victor Stinner331a6a52019-05-27 16:39:22 +0200643PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200644{
645#define CLEAR(ATTR) \
646 do { \
647 PyMem_RawFree(ATTR); \
648 ATTR = NULL; \
649 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200650
651 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200652 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200653 CLEAR(config->home);
654 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200655
Victor Stinner331a6a52019-05-27 16:39:22 +0200656 _PyWideStringList_Clear(&config->argv);
657 _PyWideStringList_Clear(&config->warnoptions);
658 _PyWideStringList_Clear(&config->xoptions);
659 _PyWideStringList_Clear(&config->module_search_paths);
660 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200661
662 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700663 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200664 CLEAR(config->prefix);
665 CLEAR(config->base_prefix);
666 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200667 CLEAR(config->base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200668 CLEAR(config->platlibdir);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200669
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200670 CLEAR(config->filesystem_encoding);
671 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200672 CLEAR(config->stdio_encoding);
673 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100674 CLEAR(config->run_command);
675 CLEAR(config->run_module);
676 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400677 CLEAR(config->check_hash_pycs_mode);
Victor Stinnere2d47a02020-06-15 16:27:47 +0200678
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200679 _PyWideStringList_Clear(&config->orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200680#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200681}
682
683
Victor Stinner8462a492019-10-01 12:06:16 +0200684void
Victor Stinner331a6a52019-05-27 16:39:22 +0200685_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200686{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200687 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200688
Victor Stinner022be022019-05-22 23:58:50 +0200689 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200690 config->isolated = -1;
691 config->use_environment = -1;
692 config->dev_mode = -1;
693 config->install_signal_handlers = 1;
694 config->use_hash_seed = -1;
695 config->faulthandler = -1;
696 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200697 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200698 config->parse_argv = 0;
699 config->site_import = -1;
700 config->bytes_warning = -1;
701 config->inspect = -1;
702 config->interactive = -1;
703 config->optimization_level = -1;
704 config->parser_debug= -1;
705 config->write_bytecode = -1;
706 config->verbose = -1;
707 config->quiet = -1;
708 config->user_site_directory = -1;
709 config->configure_c_stdio = 0;
710 config->buffered_stdio = -1;
711 config->_install_importlib = 1;
712 config->check_hash_pycs_mode = NULL;
713 config->pathconfig_warnings = -1;
714 config->_init_main = 1;
Victor Stinner252346a2020-05-01 11:33:44 +0200715 config->_isolated_interpreter = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200716#ifdef MS_WINDOWS
717 config->legacy_windows_stdio = -1;
718#endif
719}
720
721
Victor Stinner8462a492019-10-01 12:06:16 +0200722static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200723config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200724{
Victor Stinner8462a492019-10-01 12:06:16 +0200725 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200726
727 config->isolated = 0;
728 config->use_environment = 1;
729 config->site_import = 1;
730 config->bytes_warning = 0;
731 config->inspect = 0;
732 config->interactive = 0;
733 config->optimization_level = 0;
734 config->parser_debug= 0;
735 config->write_bytecode = 1;
736 config->verbose = 0;
737 config->quiet = 0;
738 config->user_site_directory = 1;
739 config->buffered_stdio = 1;
740 config->pathconfig_warnings = 1;
741#ifdef MS_WINDOWS
742 config->legacy_windows_stdio = 0;
743#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200744}
745
746
Victor Stinner8462a492019-10-01 12:06:16 +0200747void
Victor Stinner331a6a52019-05-27 16:39:22 +0200748PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200749{
Victor Stinner8462a492019-10-01 12:06:16 +0200750 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200751
Victor Stinner022be022019-05-22 23:58:50 +0200752 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200753 config->configure_c_stdio = 1;
754 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200755}
756
757
Victor Stinner8462a492019-10-01 12:06:16 +0200758void
Victor Stinner331a6a52019-05-27 16:39:22 +0200759PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200760{
Victor Stinner8462a492019-10-01 12:06:16 +0200761 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200762
Victor Stinner022be022019-05-22 23:58:50 +0200763 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200764 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200765 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200766 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200767 config->dev_mode = 0;
768 config->install_signal_handlers = 0;
769 config->use_hash_seed = 0;
770 config->faulthandler = 0;
771 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200772 config->pathconfig_warnings = 0;
773#ifdef MS_WINDOWS
774 config->legacy_windows_stdio = 0;
775#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200776}
777
778
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200779/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200780PyStatus
781PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200782{
Victor Stinner331a6a52019-05-27 16:39:22 +0200783 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
784 if (_PyStatus_EXCEPTION(status)) {
785 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200786 }
787
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200788 wchar_t *str2;
789 if (str != NULL) {
790 str2 = _PyMem_RawWcsdup(str);
791 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200792 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200793 }
794 }
795 else {
796 str2 = NULL;
797 }
798 PyMem_RawFree(*config_str);
799 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200800 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200801}
802
803
Victor Stinner331a6a52019-05-27 16:39:22 +0200804static PyStatus
805config_set_bytes_string(PyConfig *config, wchar_t **config_str,
806 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200807{
Victor Stinner331a6a52019-05-27 16:39:22 +0200808 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
809 if (_PyStatus_EXCEPTION(status)) {
810 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400811 }
812
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200813 wchar_t *str2;
814 if (str != NULL) {
815 size_t len;
816 str2 = Py_DecodeLocale(str, &len);
817 if (str2 == NULL) {
818 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200819 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200820 }
821 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200822 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200823 }
824 }
825 }
826 else {
827 str2 = NULL;
828 }
829 PyMem_RawFree(*config_str);
830 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200831 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200832}
833
834
Victor Stinner331a6a52019-05-27 16:39:22 +0200835#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
836 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400837
838
Victor Stinner70005ac2019-05-02 15:25:34 -0400839/* Decode str using Py_DecodeLocale() and set the result into *config_str.
840 Pre-initialize Python if needed to ensure that encodings are properly
841 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200842PyStatus
843PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner710e8262020-10-31 01:02:09 +0100844 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400845{
Victor Stinner331a6a52019-05-27 16:39:22 +0200846 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400847}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200848
849
Victor Stinner331a6a52019-05-27 16:39:22 +0200850PyStatus
851_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200852{
Victor Stinner331a6a52019-05-27 16:39:22 +0200853 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200854
Victor Stinner331a6a52019-05-27 16:39:22 +0200855 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200856
857#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200858#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200859 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200860 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
861 if (_PyStatus_EXCEPTION(status)) { \
862 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200863 } \
864 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100865#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200866 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200867 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200868 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200869 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200870 } while (0)
871
Victor Stinner6d1c4672019-05-20 11:02:00 +0200872 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100873 COPY_ATTR(isolated);
874 COPY_ATTR(use_environment);
875 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200876 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200877 COPY_ATTR(use_hash_seed);
878 COPY_ATTR(hash_seed);
879 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200880 COPY_ATTR(faulthandler);
881 COPY_ATTR(tracemalloc);
882 COPY_ATTR(import_time);
883 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200884 COPY_ATTR(dump_refs);
885 COPY_ATTR(malloc_stats);
886
Victor Stinner124b9eb2018-08-29 01:29:06 +0200887 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200888 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200889 COPY_WSTR_ATTR(home);
890 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200891
Victor Stinnerae239f62019-05-16 17:02:56 +0200892 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100893 COPY_WSTRLIST(argv);
894 COPY_WSTRLIST(warnoptions);
895 COPY_WSTRLIST(xoptions);
896 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200897 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200898
Victor Stinner124b9eb2018-08-29 01:29:06 +0200899 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700900 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200901 COPY_WSTR_ATTR(prefix);
902 COPY_WSTR_ATTR(base_prefix);
903 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200904 COPY_WSTR_ATTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200905 COPY_WSTR_ATTR(platlibdir);
Victor Stinner6c785c02018-08-01 17:56:14 +0200906
Victor Stinner6c785c02018-08-01 17:56:14 +0200907 COPY_ATTR(site_import);
908 COPY_ATTR(bytes_warning);
909 COPY_ATTR(inspect);
910 COPY_ATTR(interactive);
911 COPY_ATTR(optimization_level);
912 COPY_ATTR(parser_debug);
913 COPY_ATTR(write_bytecode);
914 COPY_ATTR(verbose);
915 COPY_ATTR(quiet);
916 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200917 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200918 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400919 COPY_WSTR_ATTR(filesystem_encoding);
920 COPY_WSTR_ATTR(filesystem_errors);
921 COPY_WSTR_ATTR(stdio_encoding);
922 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200923#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200924 COPY_ATTR(legacy_windows_stdio);
925#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100926 COPY_ATTR(skip_source_first_line);
927 COPY_WSTR_ATTR(run_command);
928 COPY_WSTR_ATTR(run_module);
929 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400930 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200931 COPY_ATTR(pathconfig_warnings);
932 COPY_ATTR(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200933 COPY_ATTR(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200934 COPY_WSTRLIST(orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200935
936#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200937#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200938#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200939 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200940}
941
942
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100943PyObject *
944_PyConfig_AsDict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100945{
Victor Stinner8f427482020-07-08 00:20:37 +0200946 PyObject *dict = PyDict_New();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100947 if (dict == NULL) {
948 return NULL;
949 }
950
951#define SET_ITEM(KEY, EXPR) \
952 do { \
953 PyObject *obj = (EXPR); \
954 if (obj == NULL) { \
955 goto fail; \
956 } \
957 int res = PyDict_SetItemString(dict, (KEY), obj); \
958 Py_DECREF(obj); \
959 if (res < 0) { \
960 goto fail; \
961 } \
962 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100963#define SET_ITEM_INT(ATTR) \
964 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
965#define SET_ITEM_UINT(ATTR) \
966 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100967#define FROM_WSTRING(STR) \
968 ((STR != NULL) ? \
969 PyUnicode_FromWideChar(STR, -1) \
970 : (Py_INCREF(Py_None), Py_None))
971#define SET_ITEM_WSTR(ATTR) \
972 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
973#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200974 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100975
Victor Stinner6d1c4672019-05-20 11:02:00 +0200976 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100977 SET_ITEM_INT(isolated);
978 SET_ITEM_INT(use_environment);
979 SET_ITEM_INT(dev_mode);
980 SET_ITEM_INT(install_signal_handlers);
981 SET_ITEM_INT(use_hash_seed);
982 SET_ITEM_UINT(hash_seed);
983 SET_ITEM_INT(faulthandler);
984 SET_ITEM_INT(tracemalloc);
985 SET_ITEM_INT(import_time);
986 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100987 SET_ITEM_INT(dump_refs);
988 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400989 SET_ITEM_WSTR(filesystem_encoding);
990 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100991 SET_ITEM_WSTR(pycache_prefix);
992 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200993 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100994 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100995 SET_ITEM_WSTRLIST(xoptions);
996 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200997 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100998 SET_ITEM_WSTR(home);
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100999 SET_ITEM_INT(module_search_paths_set);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001000 SET_ITEM_WSTRLIST(module_search_paths);
1001 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -07001002 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001003 SET_ITEM_WSTR(prefix);
1004 SET_ITEM_WSTR(base_prefix);
1005 SET_ITEM_WSTR(exec_prefix);
1006 SET_ITEM_WSTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +02001007 SET_ITEM_WSTR(platlibdir);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001008 SET_ITEM_INT(site_import);
1009 SET_ITEM_INT(bytes_warning);
1010 SET_ITEM_INT(inspect);
1011 SET_ITEM_INT(interactive);
1012 SET_ITEM_INT(optimization_level);
1013 SET_ITEM_INT(parser_debug);
1014 SET_ITEM_INT(write_bytecode);
1015 SET_ITEM_INT(verbose);
1016 SET_ITEM_INT(quiet);
1017 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001018 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001019 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -04001020 SET_ITEM_WSTR(stdio_encoding);
1021 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001022#ifdef MS_WINDOWS
1023 SET_ITEM_INT(legacy_windows_stdio);
1024#endif
1025 SET_ITEM_INT(skip_source_first_line);
1026 SET_ITEM_WSTR(run_command);
1027 SET_ITEM_WSTR(run_module);
1028 SET_ITEM_WSTR(run_filename);
1029 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001030 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001031 SET_ITEM_INT(pathconfig_warnings);
1032 SET_ITEM_INT(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +02001033 SET_ITEM_INT(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02001034 SET_ITEM_WSTRLIST(orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001035
1036 return dict;
1037
1038fail:
1039 Py_DECREF(dict);
1040 return NULL;
1041
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001042#undef FROM_WSTRING
1043#undef SET_ITEM
1044#undef SET_ITEM_INT
1045#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001046#undef SET_ITEM_WSTR
1047#undef SET_ITEM_WSTRLIST
1048}
1049
1050
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001051static PyObject*
1052config_dict_get(PyObject *dict, const char *name)
1053{
Serhiy Storchaka14d81dc2020-11-24 14:07:32 +02001054 PyObject *item = _PyDict_GetItemStringWithError(dict, name);
1055 if (item == NULL && !PyErr_Occurred()) {
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001056 PyErr_Format(PyExc_ValueError, "missing config key: %s", name);
1057 return NULL;
1058 }
1059 return item;
1060}
1061
1062
1063static void
1064config_dict_invalid_value(const char *name)
1065{
1066 PyErr_Format(PyExc_ValueError, "invalid config value: %s", name);
1067}
1068
1069
1070static void
1071config_dict_invalid_type(const char *name)
1072{
1073 PyErr_Format(PyExc_TypeError, "invalid config type: %s", name);
1074}
1075
1076
1077static int
1078config_dict_get_int(PyObject *dict, const char *name, int *result)
1079{
1080 PyObject *item = config_dict_get(dict, name);
1081 if (item == NULL) {
1082 return -1;
1083 }
1084 int value = _PyLong_AsInt(item);
1085 if (value == -1 && PyErr_Occurred()) {
1086 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1087 config_dict_invalid_type(name);
1088 }
Serhiy Storchaka14d81dc2020-11-24 14:07:32 +02001089 else if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001090 config_dict_invalid_value(name);
1091 }
1092 return -1;
1093 }
1094 *result = value;
1095 return 0;
1096}
1097
1098
1099static int
1100config_dict_get_ulong(PyObject *dict, const char *name, unsigned long *result)
1101{
1102 PyObject *item = config_dict_get(dict, name);
1103 if (item == NULL) {
1104 return -1;
1105 }
1106 unsigned long value = PyLong_AsUnsignedLong(item);
1107 if (value == (unsigned long)-1 && PyErr_Occurred()) {
Serhiy Storchaka14d81dc2020-11-24 14:07:32 +02001108 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1109 config_dict_invalid_type(name);
1110 }
1111 else if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
1112 config_dict_invalid_value(name);
1113 }
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001114 return -1;
1115 }
1116 *result = value;
1117 return 0;
1118}
1119
1120
1121static int
1122config_dict_get_wstr(PyObject *dict, const char *name, PyConfig *config,
1123 wchar_t **result)
1124{
1125 PyObject *item = config_dict_get(dict, name);
1126 if (item == NULL) {
1127 return -1;
1128 }
1129 PyStatus status;
1130 if (item == Py_None) {
1131 status = PyConfig_SetString(config, result, NULL);
1132 }
1133 else if (!PyUnicode_Check(item)) {
1134 config_dict_invalid_type(name);
1135 return -1;
1136 }
1137 else {
1138 wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL);
1139 if (wstr == NULL) {
1140 return -1;
1141 }
1142 status = PyConfig_SetString(config, result, wstr);
1143 PyMem_Free(wstr);
1144 }
1145 if (_PyStatus_EXCEPTION(status)) {
1146 PyErr_NoMemory();
1147 return -1;
1148 }
1149 return 0;
1150}
1151
1152
1153static int
1154config_dict_get_wstrlist(PyObject *dict, const char *name, PyConfig *config,
1155 PyWideStringList *result)
1156{
1157 PyObject *list = config_dict_get(dict, name);
1158 if (list == NULL) {
1159 return -1;
1160 }
1161
1162 if (!PyList_CheckExact(list)) {
1163 config_dict_invalid_type(name);
1164 return -1;
1165 }
1166
1167 PyWideStringList wstrlist = _PyWideStringList_INIT;
1168 for (Py_ssize_t i=0; i < PyList_GET_SIZE(list); i++) {
1169 PyObject *item = PyList_GET_ITEM(list, i);
1170
1171 if (item == Py_None) {
1172 config_dict_invalid_value(name);
1173 goto error;
1174 }
1175 else if (!PyUnicode_Check(item)) {
1176 config_dict_invalid_type(name);
1177 goto error;
1178 }
1179 wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL);
1180 if (wstr == NULL) {
1181 goto error;
1182 }
1183 PyStatus status = PyWideStringList_Append(&wstrlist, wstr);
1184 PyMem_Free(wstr);
1185 if (_PyStatus_EXCEPTION(status)) {
1186 PyErr_NoMemory();
1187 goto error;
1188 }
1189 }
1190
1191 if (_PyWideStringList_Copy(result, &wstrlist) < 0) {
1192 PyErr_NoMemory();
1193 goto error;
1194 }
1195 _PyWideStringList_Clear(&wstrlist);
1196 return 0;
1197
1198error:
1199 _PyWideStringList_Clear(&wstrlist);
1200 return -1;
1201}
1202
1203
1204int
1205_PyConfig_FromDict(PyConfig *config, PyObject *dict)
1206{
1207 if (!PyDict_Check(dict)) {
1208 PyErr_SetString(PyExc_TypeError, "dict expected");
1209 return -1;
1210 }
1211
1212#define CHECK_VALUE(NAME, TEST) \
1213 if (!(TEST)) { \
1214 config_dict_invalid_value(NAME); \
1215 return -1; \
1216 }
1217#define GET_UINT(KEY) \
1218 do { \
1219 if (config_dict_get_int(dict, #KEY, &config->KEY) < 0) { \
1220 return -1; \
1221 } \
1222 CHECK_VALUE(#KEY, config->KEY >= 0); \
1223 } while (0)
1224#define GET_WSTR(KEY) \
1225 do { \
1226 if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \
1227 return -1; \
1228 } \
1229 CHECK_VALUE(#KEY, config->KEY != NULL); \
1230 } while (0)
1231#define GET_WSTR_OPT(KEY) \
1232 do { \
1233 if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \
1234 return -1; \
1235 } \
1236 } while (0)
1237#define GET_WSTRLIST(KEY) \
1238 do { \
1239 if (config_dict_get_wstrlist(dict, #KEY, config, &config->KEY) < 0) { \
1240 return -1; \
1241 } \
1242 } while (0)
1243
1244 GET_UINT(_config_init);
1245 CHECK_VALUE("_config_init",
1246 config->_config_init == _PyConfig_INIT_COMPAT
1247 || config->_config_init == _PyConfig_INIT_PYTHON
1248 || config->_config_init == _PyConfig_INIT_ISOLATED);
1249 GET_UINT(isolated);
1250 GET_UINT(use_environment);
1251 GET_UINT(dev_mode);
1252 GET_UINT(install_signal_handlers);
1253 GET_UINT(use_hash_seed);
1254 if (config_dict_get_ulong(dict, "hash_seed", &config->hash_seed) < 0) {
1255 return -1;
1256 }
1257 CHECK_VALUE("hash_seed", config->hash_seed <= MAX_HASH_SEED);
1258 GET_UINT(faulthandler);
1259 GET_UINT(tracemalloc);
1260 GET_UINT(import_time);
1261 GET_UINT(show_ref_count);
1262 GET_UINT(dump_refs);
1263 GET_UINT(malloc_stats);
1264 GET_WSTR(filesystem_encoding);
1265 GET_WSTR(filesystem_errors);
1266 GET_WSTR_OPT(pycache_prefix);
1267 GET_UINT(parse_argv);
1268 GET_WSTRLIST(orig_argv);
1269 GET_WSTRLIST(argv);
1270 GET_WSTRLIST(xoptions);
1271 GET_WSTRLIST(warnoptions);
1272 GET_UINT(site_import);
1273 GET_UINT(bytes_warning);
1274 GET_UINT(inspect);
1275 GET_UINT(interactive);
1276 GET_UINT(optimization_level);
1277 GET_UINT(parser_debug);
1278 GET_UINT(write_bytecode);
1279 GET_UINT(verbose);
1280 GET_UINT(quiet);
1281 GET_UINT(user_site_directory);
1282 GET_UINT(configure_c_stdio);
1283 GET_UINT(buffered_stdio);
1284 GET_WSTR(stdio_encoding);
1285 GET_WSTR(stdio_errors);
1286#ifdef MS_WINDOWS
1287 GET_UINT(legacy_windows_stdio);
1288#endif
1289 GET_WSTR(check_hash_pycs_mode);
1290
1291 GET_UINT(pathconfig_warnings);
1292 GET_WSTR(program_name);
1293 GET_WSTR_OPT(pythonpath_env);
1294 GET_WSTR_OPT(home);
1295 GET_WSTR(platlibdir);
1296
Victor Stinner9e1b8282020-11-10 13:21:52 +01001297 // Path configuration output
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001298 GET_UINT(module_search_paths_set);
1299 GET_WSTRLIST(module_search_paths);
Victor Stinner9e1b8282020-11-10 13:21:52 +01001300 GET_WSTR_OPT(executable);
1301 GET_WSTR_OPT(base_executable);
1302 GET_WSTR_OPT(prefix);
1303 GET_WSTR_OPT(base_prefix);
1304 GET_WSTR_OPT(exec_prefix);
1305 GET_WSTR_OPT(base_exec_prefix);
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001306
1307 GET_UINT(skip_source_first_line);
1308 GET_WSTR_OPT(run_command);
1309 GET_WSTR_OPT(run_module);
1310 GET_WSTR_OPT(run_filename);
1311
1312 GET_UINT(_install_importlib);
1313 GET_UINT(_init_main);
1314 GET_UINT(_isolated_interpreter);
1315
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001316#undef CHECK_VALUE
1317#undef GET_UINT
1318#undef GET_WSTR
1319#undef GET_WSTR_OPT
1320 return 0;
1321}
1322
1323
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001324static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +02001325config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001326{
Victor Stinner20004952019-03-26 02:31:11 +01001327 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001328}
1329
1330
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001331/* Get a copy of the environment variable as wchar_t*.
1332 Return 0 on success, but *dest can be NULL.
1333 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001334static PyStatus
1335config_get_env_dup(PyConfig *config,
1336 wchar_t **dest,
1337 wchar_t *wname, char *name,
1338 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +02001339{
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001340 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +01001341 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +02001342
Victor Stinner20004952019-03-26 02:31:11 +01001343 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001344 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001345 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001346 }
1347
1348#ifdef MS_WINDOWS
1349 const wchar_t *var = _wgetenv(wname);
1350 if (!var || var[0] == '\0') {
1351 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001352 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001353 }
1354
Victor Stinner331a6a52019-05-27 16:39:22 +02001355 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +02001356#else
1357 const char *var = getenv(name);
1358 if (!var || var[0] == '\0') {
1359 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001360 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001361 }
1362
Victor Stinner331a6a52019-05-27 16:39:22 +02001363 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001364#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001365}
1366
1367
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001368#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001369 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001370
1371
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001372static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001373config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001374{
Victor Stinner022be022019-05-22 23:58:50 +02001375 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1376 /* Python and Isolated configuration ignore global variables */
1377 return;
1378 }
1379
Victor Stinner6c785c02018-08-01 17:56:14 +02001380#define COPY_FLAG(ATTR, VALUE) \
1381 if (config->ATTR == -1) { \
1382 config->ATTR = VALUE; \
1383 }
1384#define COPY_NOT_FLAG(ATTR, VALUE) \
1385 if (config->ATTR == -1) { \
1386 config->ATTR = !(VALUE); \
1387 }
1388
Victor Stinner20004952019-03-26 02:31:11 +01001389 COPY_FLAG(isolated, Py_IsolatedFlag);
1390 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001391 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1392 COPY_FLAG(inspect, Py_InspectFlag);
1393 COPY_FLAG(interactive, Py_InteractiveFlag);
1394 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1395 COPY_FLAG(parser_debug, Py_DebugFlag);
1396 COPY_FLAG(verbose, Py_VerboseFlag);
1397 COPY_FLAG(quiet, Py_QuietFlag);
1398#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001399 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1400#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001401 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001402
Victor Stinner6c785c02018-08-01 17:56:14 +02001403 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1404 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1405 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1406 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1407
Victor Stinner6c785c02018-08-01 17:56:14 +02001408#undef COPY_FLAG
1409#undef COPY_NOT_FLAG
1410}
1411
1412
1413/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001414static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001415config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001416{
1417#define COPY_FLAG(ATTR, VAR) \
1418 if (config->ATTR != -1) { \
1419 VAR = config->ATTR; \
1420 }
1421#define COPY_NOT_FLAG(ATTR, VAR) \
1422 if (config->ATTR != -1) { \
1423 VAR = !config->ATTR; \
1424 }
1425
Victor Stinner20004952019-03-26 02:31:11 +01001426 COPY_FLAG(isolated, Py_IsolatedFlag);
1427 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001428 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1429 COPY_FLAG(inspect, Py_InspectFlag);
1430 COPY_FLAG(interactive, Py_InteractiveFlag);
1431 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1432 COPY_FLAG(parser_debug, Py_DebugFlag);
1433 COPY_FLAG(verbose, Py_VerboseFlag);
1434 COPY_FLAG(quiet, Py_QuietFlag);
1435#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001436 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1437#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001438 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001439
Victor Stinner6c785c02018-08-01 17:56:14 +02001440 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1441 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1442 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1443 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1444
Victor Stinner6c785c02018-08-01 17:56:14 +02001445 /* Random or non-zero hash seed */
1446 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1447 config->hash_seed != 0);
1448
1449#undef COPY_FLAG
1450#undef COPY_NOT_FLAG
1451}
1452
1453
1454/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1455 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001456static PyStatus
1457config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001458{
Victor Stinner331a6a52019-05-27 16:39:22 +02001459 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001460
Victor Stinner6c785c02018-08-01 17:56:14 +02001461 /* If Py_SetProgramName() was called, use its value */
1462 const wchar_t *program_name = _Py_path_config.program_name;
1463 if (program_name != NULL) {
1464 config->program_name = _PyMem_RawWcsdup(program_name);
1465 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001466 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001467 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001468 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001469 }
1470
1471#ifdef __APPLE__
1472 /* On MacOS X, when the Python interpreter is embedded in an
1473 application bundle, it gets executed by a bootstrapping script
1474 that does os.execve() with an argv[0] that's different from the
1475 actual Python executable. This is needed to keep the Finder happy,
1476 or rather, to work around Apple's overly strict requirements of
1477 the process name. However, we still need a usable sys.executable,
1478 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001479 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001480 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001481 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001482 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001483 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1484 "PYTHONEXECUTABLE environment variable");
1485 if (_PyStatus_EXCEPTION(status)) {
1486 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001487 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001488 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001489 }
1490#ifdef WITH_NEXT_FRAMEWORK
1491 else {
1492 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1493 if (pyvenv_launcher && *pyvenv_launcher) {
1494 /* Used by Mac/Tools/pythonw.c to forward
1495 * the argv0 of the stub executable
1496 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001497 status = CONFIG_SET_BYTES_STR(config,
1498 &config->program_name,
1499 pyvenv_launcher,
1500 "__PYVENV_LAUNCHER__ environment variable");
1501 if (_PyStatus_EXCEPTION(status)) {
1502 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001503 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001504
1505 /*
1506 * This environment variable is used to communicate between
1507 * the stub launcher and the real interpreter and isn't needed
1508 * beyond this point.
1509 *
1510 * Clean up to avoid problems when launching other programs
1511 * later on.
1512 */
1513 (void)unsetenv("__PYVENV_LAUNCHER__");
1514
Victor Stinner331a6a52019-05-27 16:39:22 +02001515 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001516 }
1517 }
1518#endif /* WITH_NEXT_FRAMEWORK */
1519#endif /* __APPLE__ */
1520
Victor Stinnerfed02e12019-05-17 11:12:09 +02001521 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001522 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001523 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1524 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1525 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001526 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001527 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001528 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001529 }
1530
Victor Stinnerfed02e12019-05-17 11:12:09 +02001531 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001532#ifdef MS_WINDOWS
1533 const wchar_t *default_program_name = L"python";
1534#else
1535 const wchar_t *default_program_name = L"python3";
1536#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001537 status = PyConfig_SetString(config, &config->program_name,
1538 default_program_name);
1539 if (_PyStatus_EXCEPTION(status)) {
1540 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001541 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001542 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001543}
1544
Victor Stinner331a6a52019-05-27 16:39:22 +02001545static PyStatus
1546config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001547{
1548 assert(config->executable == NULL);
1549
1550 /* If Py_SetProgramFullPath() was called, use its value */
1551 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1552 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001553 PyStatus status = PyConfig_SetString(config,
1554 &config->executable,
1555 program_full_path);
1556 if (_PyStatus_EXCEPTION(status)) {
1557 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001558 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001559 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001560 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001561 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001562}
Victor Stinner6c785c02018-08-01 17:56:14 +02001563
Victor Stinner4fffd382019-03-06 01:44:31 +01001564
Victor Stinner6c785c02018-08-01 17:56:14 +02001565static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001566config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001567{
Victor Stinner74f65682019-03-15 15:08:05 +01001568 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001569}
1570
1571
Victor Stinner331a6a52019-05-27 16:39:22 +02001572static PyStatus
1573config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001574{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001575 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001576
1577 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001578 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001579 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001580 PyStatus status = PyConfig_SetString(config, &config->home, home);
1581 if (_PyStatus_EXCEPTION(status)) {
1582 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001583 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001584 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001585 }
1586
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001587 return CONFIG_GET_ENV_DUP(config, &config->home,
1588 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001589}
1590
Victor Stinner331a6a52019-05-27 16:39:22 +02001591static PyStatus
1592config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001593{
Victor Stinner331a6a52019-05-27 16:39:22 +02001594 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001595
1596 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1597 /* Convert a text seed to a numeric one */
1598 if (seed_text && strcmp(seed_text, "random") != 0) {
1599 const char *endptr = seed_text;
1600 unsigned long seed;
1601 errno = 0;
1602 seed = strtoul(seed_text, (char **)&endptr, 10);
1603 if (*endptr != '\0'
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001604 || seed > MAX_HASH_SEED
Victor Stinner6c785c02018-08-01 17:56:14 +02001605 || (errno == ERANGE && seed == ULONG_MAX))
1606 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001607 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001608 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001609 }
1610 /* Use a specific hash */
1611 config->use_hash_seed = 1;
1612 config->hash_seed = seed;
1613 }
1614 else {
1615 /* Use a random hash */
1616 config->use_hash_seed = 0;
1617 config->hash_seed = 0;
1618 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001619 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001620}
1621
1622
Victor Stinner6c785c02018-08-01 17:56:14 +02001623static int
1624config_wstr_to_int(const wchar_t *wstr, int *result)
1625{
1626 const wchar_t *endptr = wstr;
1627 errno = 0;
1628 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1629 if (*endptr != '\0' || errno == ERANGE) {
1630 return -1;
1631 }
1632 if (value < INT_MIN || value > INT_MAX) {
1633 return -1;
1634 }
1635
1636 *result = (int)value;
1637 return 0;
1638}
1639
1640
Victor Stinner331a6a52019-05-27 16:39:22 +02001641static PyStatus
1642config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001643{
Victor Stinner331a6a52019-05-27 16:39:22 +02001644 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001645 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001646
Victor Stinner6c785c02018-08-01 17:56:14 +02001647 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001648 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1649 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1650 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1651 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001652
1653 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001654 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001655 if (dont_write_bytecode) {
1656 config->write_bytecode = 0;
1657 }
1658
1659 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001660 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001661 if (no_user_site_directory) {
1662 config->user_site_directory = 0;
1663 }
1664
1665 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001666 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001667 if (unbuffered_stdio) {
1668 config->buffered_stdio = 0;
1669 }
1670
1671#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001672 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinnere662c392020-11-01 23:07:23 +01001673 "PYTHONLEGACYWINDOWSSTDIO");
Victor Stinner6c785c02018-08-01 17:56:14 +02001674#endif
1675
Victor Stinner331a6a52019-05-27 16:39:22 +02001676 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001677 config->dump_refs = 1;
1678 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001679 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001680 config->malloc_stats = 1;
1681 }
1682
Victor Stinner331a6a52019-05-27 16:39:22 +02001683 if (config->pythonpath_env == NULL) {
1684 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1685 L"PYTHONPATH", "PYTHONPATH");
1686 if (_PyStatus_EXCEPTION(status)) {
1687 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001688 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001689 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001690
Sandro Mani8f023a22020-06-08 17:28:11 +02001691 if(config->platlibdir == NULL) {
1692 status = CONFIG_GET_ENV_DUP(config, &config->platlibdir,
1693 L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR");
1694 if (_PyStatus_EXCEPTION(status)) {
1695 return status;
1696 }
1697 }
1698
Victor Stinner6c785c02018-08-01 17:56:14 +02001699 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001700 status = config_init_hash_seed(config);
1701 if (_PyStatus_EXCEPTION(status)) {
1702 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001703 }
1704 }
1705
Victor Stinner331a6a52019-05-27 16:39:22 +02001706 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001707}
1708
1709
Victor Stinner331a6a52019-05-27 16:39:22 +02001710static PyStatus
1711config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001712{
1713 int nframe;
1714 int valid;
1715
Victor Stinner331a6a52019-05-27 16:39:22 +02001716 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001717 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001718 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001719 valid = (nframe >= 0);
1720 }
1721 else {
1722 valid = 0;
1723 }
1724 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001725 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001726 }
1727 config->tracemalloc = nframe;
1728 }
1729
1730 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1731 if (xoption) {
1732 const wchar_t *sep = wcschr(xoption, L'=');
1733 if (sep) {
1734 if (!config_wstr_to_int(sep + 1, &nframe)) {
1735 valid = (nframe >= 0);
1736 }
1737 else {
1738 valid = 0;
1739 }
1740 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001741 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1742 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001743 }
1744 }
1745 else {
1746 /* -X tracemalloc behaves as -X tracemalloc=1 */
1747 nframe = 1;
1748 }
1749 config->tracemalloc = nframe;
1750 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001751 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001752}
1753
1754
Victor Stinner331a6a52019-05-27 16:39:22 +02001755static PyStatus
1756config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001757{
1758 assert(config->pycache_prefix == NULL);
1759
1760 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1761 if (xoption) {
1762 const wchar_t *sep = wcschr(xoption, L'=');
1763 if (sep && wcslen(sep) > 1) {
1764 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1765 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001766 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001767 }
1768 }
1769 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001770 // PYTHONPYCACHEPREFIX env var ignored
1771 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001772 config->pycache_prefix = NULL;
1773 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001774 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001775 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001776
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001777 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1778 L"PYTHONPYCACHEPREFIX",
1779 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001780}
1781
1782
Victor Stinner331a6a52019-05-27 16:39:22 +02001783static PyStatus
1784config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001785{
1786 /* More complex options configured by env var and -X option */
1787 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001788 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001789 || config_get_xoption(config, L"faulthandler")) {
1790 config->faulthandler = 1;
1791 }
1792 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001793 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001794 || config_get_xoption(config, L"importtime")) {
1795 config->import_time = 1;
1796 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001797
Victor Stinner331a6a52019-05-27 16:39:22 +02001798 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001799 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001800 status = config_init_tracemalloc(config);
1801 if (_PyStatus_EXCEPTION(status)) {
1802 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001803 }
1804 }
1805
1806 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001807 status = config_init_pycache_prefix(config);
1808 if (_PyStatus_EXCEPTION(status)) {
1809 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001810 }
1811 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001812 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001813}
1814
1815
Victor Stinner709d23d2019-05-02 14:56:30 -04001816static const wchar_t *
Victor Stinner710e8262020-10-31 01:02:09 +01001817config_get_stdio_errors(const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001818{
Victor Stinner710e8262020-10-31 01:02:09 +01001819 if (preconfig->utf8_mode) {
1820 /* UTF-8 Mode uses UTF-8/surrogateescape */
1821 return L"surrogateescape";
1822 }
1823
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001824#ifndef MS_WINDOWS
1825 const char *loc = setlocale(LC_CTYPE, NULL);
1826 if (loc != NULL) {
1827 /* surrogateescape is the default in the legacy C and POSIX locales */
1828 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001829 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001830 }
1831
1832#ifdef PY_COERCE_C_LOCALE
1833 /* surrogateescape is the default in locale coercion target locales */
1834 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001835 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001836 }
1837#endif
1838 }
1839
Victor Stinner709d23d2019-05-02 14:56:30 -04001840 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001841#else
1842 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001843 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001844#endif
1845}
1846
1847
Victor Stinner82458b62020-11-01 20:59:35 +01001848// See also config_get_fs_encoding()
Victor Stinner331a6a52019-05-27 16:39:22 +02001849static PyStatus
Victor Stinner710e8262020-10-31 01:02:09 +01001850config_get_locale_encoding(PyConfig *config, const PyPreConfig *preconfig,
1851 wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001852{
Victor Stinnere662c392020-11-01 23:07:23 +01001853 wchar_t *encoding = _Py_GetLocaleEncoding();
Victor Stinner82458b62020-11-01 20:59:35 +01001854 if (encoding == NULL) {
Victor Stinnere662c392020-11-01 23:07:23 +01001855 return _PyStatus_NO_MEMORY();
Victor Stinner710e8262020-10-31 01:02:09 +01001856 }
Victor Stinner82458b62020-11-01 20:59:35 +01001857 PyStatus status = PyConfig_SetString(config, locale_encoding, encoding);
1858 PyMem_RawFree(encoding);
1859 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001860}
1861
1862
Victor Stinner331a6a52019-05-27 16:39:22 +02001863static PyStatus
1864config_init_stdio_encoding(PyConfig *config,
1865 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001866{
Victor Stinner331a6a52019-05-27 16:39:22 +02001867 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001868
Victor Stinner35297182020-11-04 11:20:10 +01001869 /* If Py_SetStandardStreamEncoding() has been called, use its
1870 arguments if they are not NULL. */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001871 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001872 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1873 _Py_StandardStreamEncoding,
1874 "_Py_StandardStreamEncoding");
1875 if (_PyStatus_EXCEPTION(status)) {
1876 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001877 }
1878 }
1879
1880 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001881 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1882 _Py_StandardStreamErrors,
1883 "_Py_StandardStreamErrors");
1884 if (_PyStatus_EXCEPTION(status)) {
1885 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001886 }
1887 }
1888
Victor Stinner35297182020-11-04 11:20:10 +01001889 // Exit if encoding and errors are defined
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001890 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001891 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001892 }
1893
1894 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001895 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001896 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001897 char *pythonioencoding = _PyMem_RawStrdup(opt);
1898 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001899 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001900 }
1901
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001902 char *errors = strchr(pythonioencoding, ':');
1903 if (errors) {
1904 *errors = '\0';
1905 errors++;
1906 if (!errors[0]) {
1907 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001908 }
1909 }
1910
1911 /* Does PYTHONIOENCODING contain an encoding? */
1912 if (pythonioencoding[0]) {
1913 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001914 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1915 pythonioencoding,
1916 "PYTHONIOENCODING environment variable");
1917 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001918 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001919 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001920 }
1921 }
1922
1923 /* If the encoding is set but not the error handler,
1924 use "strict" error handler by default.
1925 PYTHONIOENCODING=latin1 behaves as
1926 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001927 if (!errors) {
1928 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001929 }
1930 }
1931
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001932 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001933 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1934 errors,
1935 "PYTHONIOENCODING environment variable");
1936 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001937 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001938 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001939 }
1940 }
1941
1942 PyMem_RawFree(pythonioencoding);
1943 }
1944
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001945 /* Choose the default error handler based on the current locale. */
1946 if (config->stdio_encoding == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001947 status = config_get_locale_encoding(config, preconfig,
1948 &config->stdio_encoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001949 if (_PyStatus_EXCEPTION(status)) {
1950 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001951 }
1952 }
1953 if (config->stdio_errors == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001954 const wchar_t *errors = config_get_stdio_errors(preconfig);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001955 assert(errors != NULL);
1956
Victor Stinner331a6a52019-05-27 16:39:22 +02001957 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1958 if (_PyStatus_EXCEPTION(status)) {
1959 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001960 }
1961 }
1962
Victor Stinner331a6a52019-05-27 16:39:22 +02001963 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001964}
1965
1966
Victor Stinner710e8262020-10-31 01:02:09 +01001967// See also config_get_locale_encoding()
1968static PyStatus
1969config_get_fs_encoding(PyConfig *config, const PyPreConfig *preconfig,
1970 wchar_t **fs_encoding)
1971{
1972#ifdef _Py_FORCE_UTF8_FS_ENCODING
1973 return PyConfig_SetString(config, fs_encoding, L"utf-8");
1974#elif defined(MS_WINDOWS)
1975 const wchar_t *encoding;
1976 if (preconfig->legacy_windows_fs_encoding) {
1977 // Legacy Windows filesystem encoding: mbcs/replace
1978 encoding = L"mbcs";
1979 }
1980 else {
1981 // Windows defaults to utf-8/surrogatepass (PEP 529)
1982 encoding = L"utf-8";
1983 }
1984 return PyConfig_SetString(config, fs_encoding, encoding);
1985#else // !MS_WINDOWS
1986 if (preconfig->utf8_mode) {
1987 return PyConfig_SetString(config, fs_encoding, L"utf-8");
1988 }
Victor Stinner35297182020-11-04 11:20:10 +01001989
1990 if (_Py_GetForceASCII()) {
Victor Stinner710e8262020-10-31 01:02:09 +01001991 return PyConfig_SetString(config, fs_encoding, L"ascii");
1992 }
Victor Stinner35297182020-11-04 11:20:10 +01001993
1994 return config_get_locale_encoding(config, preconfig, fs_encoding);
Victor Stinner710e8262020-10-31 01:02:09 +01001995#endif // !MS_WINDOWS
1996}
1997
1998
Victor Stinner331a6a52019-05-27 16:39:22 +02001999static PyStatus
2000config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002001{
Victor Stinner331a6a52019-05-27 16:39:22 +02002002 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002003
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002004 if (config->filesystem_encoding == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01002005 status = config_get_fs_encoding(config, preconfig,
2006 &config->filesystem_encoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02002007 if (_PyStatus_EXCEPTION(status)) {
2008 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002009 }
2010 }
2011
2012 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04002013 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04002014#ifdef MS_WINDOWS
2015 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04002016 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04002017 }
2018 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04002019 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04002020 }
2021#else
Victor Stinner709d23d2019-05-02 14:56:30 -04002022 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04002023#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02002024 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
2025 if (_PyStatus_EXCEPTION(status)) {
2026 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002027 }
2028 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002029 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002030}
2031
2032
Victor Stinner331a6a52019-05-27 16:39:22 +02002033static PyStatus
Victor Stinner9e1b8282020-11-10 13:21:52 +01002034config_read(PyConfig *config, int compute_path_config)
Victor Stinner6c785c02018-08-01 17:56:14 +02002035{
Victor Stinner331a6a52019-05-27 16:39:22 +02002036 PyStatus status;
2037 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01002038
Victor Stinner20004952019-03-26 02:31:11 +01002039 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002040 status = config_read_env_vars(config);
2041 if (_PyStatus_EXCEPTION(status)) {
2042 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002043 }
2044 }
2045
2046 /* -X options */
2047 if (config_get_xoption(config, L"showrefcount")) {
2048 config->show_ref_count = 1;
2049 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002050
Victor Stinner331a6a52019-05-27 16:39:22 +02002051 status = config_read_complex_options(config);
2052 if (_PyStatus_EXCEPTION(status)) {
2053 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002054 }
2055
Victor Stinner6c785c02018-08-01 17:56:14 +02002056 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002057 status = config_init_home(config);
2058 if (_PyStatus_EXCEPTION(status)) {
2059 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002060 }
2061 }
2062
Steve Dower177a41a2018-11-17 20:41:48 -08002063 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002064 status = config_init_executable(config);
2065 if (_PyStatus_EXCEPTION(status)) {
2066 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08002067 }
2068 }
2069
Sandro Mani8f023a22020-06-08 17:28:11 +02002070 if(config->platlibdir == NULL) {
2071 status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR,
2072 "PLATLIBDIR macro");
2073 if (_PyStatus_EXCEPTION(status)) {
2074 return status;
2075 }
2076 }
2077
Victor Stinnerace3f9a2020-11-10 21:10:22 +01002078 if (config->_install_importlib) {
2079 status = _PyConfig_InitPathConfig(config, compute_path_config);
Victor Stinner331a6a52019-05-27 16:39:22 +02002080 if (_PyStatus_EXCEPTION(status)) {
2081 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002082 }
2083 }
2084
2085 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01002086 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02002087 if (config->faulthandler < 0) {
2088 config->faulthandler = 1;
2089 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002090 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002091 if (config->faulthandler < 0) {
2092 config->faulthandler = 0;
2093 }
2094 if (config->tracemalloc < 0) {
2095 config->tracemalloc = 0;
2096 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002097 if (config->use_hash_seed < 0) {
2098 config->use_hash_seed = 0;
2099 config->hash_seed = 0;
2100 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002101
Victor Stinner70fead22018-08-29 13:45:34 +02002102 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002103 status = config_init_fs_encoding(config, preconfig);
2104 if (_PyStatus_EXCEPTION(status)) {
2105 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002106 }
2107 }
2108
Victor Stinner331a6a52019-05-27 16:39:22 +02002109 status = config_init_stdio_encoding(config, preconfig);
2110 if (_PyStatus_EXCEPTION(status)) {
2111 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02002112 }
2113
Victor Stinner62599762019-03-15 16:03:23 +01002114 if (config->argv.length < 1) {
2115 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002116 status = PyWideStringList_Append(&config->argv, L"");
2117 if (_PyStatus_EXCEPTION(status)) {
2118 return status;
Victor Stinner62599762019-03-15 16:03:23 +01002119 }
2120 }
Victor Stinner870b0352019-05-17 03:15:12 +02002121
2122 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002123 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
2124 L"default");
2125 if (_PyStatus_EXCEPTION(status)) {
2126 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002127 }
2128 }
2129
2130 if (config->configure_c_stdio < 0) {
2131 config->configure_c_stdio = 1;
2132 }
2133
Victor Stinnerdc42af82020-11-05 18:58:07 +01002134 // Only parse arguments once.
2135 if (config->parse_argv == 1) {
2136 config->parse_argv = 2;
2137 }
2138
Victor Stinner331a6a52019-05-27 16:39:22 +02002139 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02002140}
Victor Stinner5ed69952018-11-06 15:59:52 +01002141
2142
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002143static void
Victor Stinner331a6a52019-05-27 16:39:22 +02002144config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002145{
2146#if defined(MS_WINDOWS) || defined(__CYGWIN__)
2147 /* don't translate newlines (\r\n <=> \n) */
2148 _setmode(fileno(stdin), O_BINARY);
2149 _setmode(fileno(stdout), O_BINARY);
2150 _setmode(fileno(stderr), O_BINARY);
2151#endif
2152
2153 if (!config->buffered_stdio) {
2154#ifdef HAVE_SETVBUF
2155 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
2156 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
2157 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
2158#else /* !HAVE_SETVBUF */
2159 setbuf(stdin, (char *)NULL);
2160 setbuf(stdout, (char *)NULL);
2161 setbuf(stderr, (char *)NULL);
2162#endif /* !HAVE_SETVBUF */
2163 }
2164 else if (config->interactive) {
2165#ifdef MS_WINDOWS
2166 /* Doesn't have to have line-buffered -- use unbuffered */
2167 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
2168 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
2169#else /* !MS_WINDOWS */
2170#ifdef HAVE_SETVBUF
2171 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
2172 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
2173#endif /* HAVE_SETVBUF */
2174#endif /* !MS_WINDOWS */
2175 /* Leave stderr alone - it should be unbuffered anyway. */
2176 }
2177}
2178
2179
2180/* Write the configuration:
2181
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002182 - set Py_xxx global configuration variables
2183 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinnere81f6e62020-06-08 18:12:59 +02002184PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +02002185_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002186{
Victor Stinner331a6a52019-05-27 16:39:22 +02002187 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002188
2189 if (config->configure_c_stdio) {
2190 config_init_stdio(config);
2191 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002192
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002193 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02002194 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002195 preconfig->isolated = config->isolated;
2196 preconfig->use_environment = config->use_environment;
2197 preconfig->dev_mode = config->dev_mode;
Victor Stinnere81f6e62020-06-08 18:12:59 +02002198
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002199 if (_Py_SetArgcArgv(config->orig_argv.length,
2200 config->orig_argv.items) < 0)
Victor Stinnere81f6e62020-06-08 18:12:59 +02002201 {
2202 return _PyStatus_NO_MEMORY();
2203 }
2204 return _PyStatus_OK();
Victor Stinner5ed69952018-11-06 15:59:52 +01002205}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002206
2207
Victor Stinner331a6a52019-05-27 16:39:22 +02002208/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002209
2210static void
Victor Stinner2f549082019-03-29 15:13:46 +01002211config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002212{
Victor Stinner2f549082019-03-29 15:13:46 +01002213 FILE *f = error ? stderr : stdout;
2214
2215 fprintf(f, usage_line, program);
2216 if (error)
2217 fprintf(f, "Try `python -h' for more information.\n");
2218 else {
2219 fputs(usage_1, f);
2220 fputs(usage_2, f);
2221 fputs(usage_3, f);
2222 fprintf(f, usage_4, (wint_t)DELIM);
2223 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
2224 fputs(usage_6, f);
2225 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002226}
2227
2228
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002229/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02002230static PyStatus
2231config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02002232 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002233{
Victor Stinner331a6a52019-05-27 16:39:22 +02002234 PyStatus status;
2235 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01002236 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02002237 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01002238
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002239 _PyOS_ResetGetOpt();
2240 do {
2241 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01002242 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002243 if (c == EOF) {
2244 break;
2245 }
2246
2247 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01002248 if (config->run_command == NULL) {
2249 /* -c is the last option; following arguments
2250 that look like options are left for the
2251 command to interpret. */
2252 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
2253 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
2254 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002255 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01002256 }
2257 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
2258 command[len - 2] = '\n';
2259 command[len - 1] = 0;
2260 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002261 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002262 break;
2263 }
2264
2265 if (c == 'm') {
2266 /* -m is the last option; following arguments
2267 that look like options are left for the
2268 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002269 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01002270 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
2271 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002272 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01002273 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002274 }
2275 break;
2276 }
2277
2278 switch (c) {
2279 case 0:
2280 // Handle long option.
2281 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002282 if (wcscmp(_PyOS_optarg, L"always") == 0
2283 || wcscmp(_PyOS_optarg, L"never") == 0
2284 || wcscmp(_PyOS_optarg, L"default") == 0)
2285 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002286 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
2287 _PyOS_optarg);
2288 if (_PyStatus_EXCEPTION(status)) {
2289 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002290 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002291 } else {
2292 fprintf(stderr, "--check-hash-based-pycs must be one of "
2293 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02002294 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002295 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002296 }
2297 break;
2298
2299 case 'b':
2300 config->bytes_warning++;
2301 break;
2302
2303 case 'd':
2304 config->parser_debug++;
2305 break;
2306
2307 case 'i':
2308 config->inspect++;
2309 config->interactive++;
2310 break;
2311
Victor Stinner6dcb5422019-03-05 02:44:12 +01002312 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002313 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01002314 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002315 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002316 break;
2317
2318 /* case 'J': reserved for Jython */
2319
2320 case 'O':
2321 config->optimization_level++;
2322 break;
2323
2324 case 'B':
2325 config->write_bytecode = 0;
2326 break;
2327
2328 case 's':
2329 config->user_site_directory = 0;
2330 break;
2331
2332 case 'S':
2333 config->site_import = 0;
2334 break;
2335
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002336 case 't':
2337 /* ignored for backwards compatibility */
2338 break;
2339
2340 case 'u':
2341 config->buffered_stdio = 0;
2342 break;
2343
2344 case 'v':
2345 config->verbose++;
2346 break;
2347
2348 case 'x':
2349 config->skip_source_first_line = 1;
2350 break;
2351
2352 case 'h':
2353 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02002354 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002355 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002356
2357 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01002358 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002359 break;
2360
2361 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002362 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2363 if (_PyStatus_EXCEPTION(status)) {
2364 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002365 }
2366 break;
2367
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002368 case 'q':
2369 config->quiet++;
2370 break;
2371
2372 case 'R':
2373 config->use_hash_seed = 0;
2374 break;
2375
2376 /* This space reserved for other options */
2377
2378 default:
2379 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002380 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002381 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002382 }
2383 } while (1);
2384
Victor Stinner2f549082019-03-29 15:13:46 +01002385 if (print_version) {
2386 printf("Python %s\n",
2387 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002388 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002389 }
2390
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002391 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002392 && _PyOS_optind < argv->length
2393 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002394 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002395 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002396 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002397 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002398 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002399 }
2400 }
2401
2402 if (config->run_command != NULL || config->run_module != NULL) {
2403 /* Backup _PyOS_optind */
2404 _PyOS_optind--;
2405 }
2406
Victor Stinnerae239f62019-05-16 17:02:56 +02002407 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002408
Victor Stinner331a6a52019-05-27 16:39:22 +02002409 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002410}
2411
2412
2413#ifdef MS_WINDOWS
2414# define WCSTOK wcstok_s
2415#else
2416# define WCSTOK wcstok
2417#endif
2418
2419/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002420static PyStatus
2421config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002422{
Victor Stinner331a6a52019-05-27 16:39:22 +02002423 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002424 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2425 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002426 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002427 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002428 if (_PyStatus_EXCEPTION(status)) {
2429 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002430 }
2431
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002432 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002433 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002434 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002435 }
2436
2437
2438 wchar_t *warning, *context = NULL;
2439 for (warning = WCSTOK(env, L",", &context);
2440 warning != NULL;
2441 warning = WCSTOK(NULL, L",", &context))
2442 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002443 status = PyWideStringList_Append(warnoptions, warning);
2444 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002445 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002446 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002447 }
2448 }
2449 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002450 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002451}
2452
2453
Victor Stinner331a6a52019-05-27 16:39:22 +02002454static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002455warnoptions_append(PyConfig *config, PyWideStringList *options,
2456 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002457{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002458 /* config_init_warnoptions() add existing config warnoptions at the end:
2459 ensure that the new option is not already present in this list to
2460 prevent change the options order whne config_init_warnoptions() is
2461 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002462 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002463 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002464 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002465 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002466 if (_PyWideStringList_Find(options, option)) {
2467 /* Already present: do nothing */
2468 return _PyStatus_OK();
2469 }
2470 return PyWideStringList_Append(options, option);
2471}
2472
2473
2474static PyStatus
2475warnoptions_extend(PyConfig *config, PyWideStringList *options,
2476 const PyWideStringList *options2)
2477{
2478 const Py_ssize_t len = options2->length;
2479 wchar_t *const *items = options2->items;
2480
2481 for (Py_ssize_t i = 0; i < len; i++) {
2482 PyStatus status = warnoptions_append(config, options, items[i]);
2483 if (_PyStatus_EXCEPTION(status)) {
2484 return status;
2485 }
2486 }
2487 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002488}
2489
2490
Victor Stinner331a6a52019-05-27 16:39:22 +02002491static PyStatus
2492config_init_warnoptions(PyConfig *config,
2493 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002494 const PyWideStringList *env_warnoptions,
2495 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002496{
Victor Stinner331a6a52019-05-27 16:39:22 +02002497 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002498 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002499
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002500 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002501 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002502 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002503 * - PyConfig.dev_mode: "default" filter
2504 * - PYTHONWARNINGS environment variable
2505 * - '-W' command line options
2506 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2507 * "default::BytesWarning" or "error::BytesWarning" filter
2508 * - early PySys_AddWarnOption() calls
2509 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002510 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002511 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2512 * module works on the basis of "the most recently added filter will be
2513 * checked first", we add the lowest precedence entries first so that later
2514 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002515 */
2516
Victor Stinner20004952019-03-26 02:31:11 +01002517 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002518 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002519 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002520 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002521 }
2522 }
2523
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002524 status = warnoptions_extend(config, &options, env_warnoptions);
2525 if (_PyStatus_EXCEPTION(status)) {
2526 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002527 }
2528
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002529 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2530 if (_PyStatus_EXCEPTION(status)) {
2531 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002532 }
2533
2534 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2535 * don't even try to emit a warning, so we skip setting the filter in that
2536 * case.
2537 */
2538 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002539 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002540 if (config->bytes_warning> 1) {
2541 filter = L"error::BytesWarning";
2542 }
2543 else {
2544 filter = L"default::BytesWarning";
2545 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002546 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002547 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002548 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002549 }
2550 }
Victor Stinner120b7072019-08-23 18:03:08 +01002551
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002552 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002553 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002554 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002555 }
2556
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002557 /* Always add all PyConfig.warnoptions options */
2558 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2559 if (_PyStatus_EXCEPTION(status)) {
2560 goto error;
2561 }
2562
2563 _PyWideStringList_Clear(&config->warnoptions);
2564 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002565 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002566
2567error:
2568 _PyWideStringList_Clear(&options);
2569 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002570}
2571
2572
Victor Stinner331a6a52019-05-27 16:39:22 +02002573static PyStatus
2574config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002575{
Victor Stinner331a6a52019-05-27 16:39:22 +02002576 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002577 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002578
Victor Stinner74f65682019-03-15 15:08:05 +01002579 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002580 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002581 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002582 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2583 if (_PyStatus_EXCEPTION(status)) {
2584 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002585 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002586 }
2587 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002588 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002589 slice.length = cmdline_argv->length - opt_index;
2590 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002591 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2592 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002593 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002594 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002595 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002596
2597 wchar_t *arg0 = NULL;
2598 if (config->run_command != NULL) {
2599 /* Force sys.argv[0] = '-c' */
2600 arg0 = L"-c";
2601 }
2602 else if (config->run_module != NULL) {
2603 /* Force sys.argv[0] = '-m'*/
2604 arg0 = L"-m";
2605 }
Victor Stinner3939c322019-06-25 15:02:43 +02002606
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002607 if (arg0 != NULL) {
2608 arg0 = _PyMem_RawWcsdup(arg0);
2609 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002610 _PyWideStringList_Clear(&config_argv);
2611 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002612 }
2613
Victor Stinnerfa153762019-03-20 04:25:38 +01002614 PyMem_RawFree(config_argv.items[0]);
2615 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002616 }
2617
Victor Stinner331a6a52019-05-27 16:39:22 +02002618 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002619 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002620 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002621}
2622
2623
Victor Stinner331a6a52019-05-27 16:39:22 +02002624static PyStatus
2625core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002626{
Victor Stinner331a6a52019-05-27 16:39:22 +02002627 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002628
Victor Stinnerdc42af82020-11-05 18:58:07 +01002629 if (config->parse_argv == 1) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002630 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2631 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002632 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002633 }
2634
Victor Stinner331a6a52019-05-27 16:39:22 +02002635 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002636
2637 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2638 if (_PyStatus_EXCEPTION(status)) {
2639 return status;
2640 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002641
Victor Stinner331a6a52019-05-27 16:39:22 +02002642 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002643
Victor Stinner331a6a52019-05-27 16:39:22 +02002644 status = _PyPreCmdline_Read(precmdline, &preconfig);
2645 if (_PyStatus_EXCEPTION(status)) {
2646 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002647 }
2648
Victor Stinner331a6a52019-05-27 16:39:22 +02002649 status = _PyPreCmdline_SetConfig(precmdline, config);
2650 if (_PyStatus_EXCEPTION(status)) {
2651 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002652 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002653 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002654}
2655
2656
Victor Stinner3939c322019-06-25 15:02:43 +02002657/* Get run_filename absolute path */
2658static PyStatus
2659config_run_filename_abspath(PyConfig *config)
2660{
2661 if (!config->run_filename) {
2662 return _PyStatus_OK();
2663 }
2664
2665#ifndef MS_WINDOWS
2666 if (_Py_isabs(config->run_filename)) {
2667 /* path is already absolute */
2668 return _PyStatus_OK();
2669 }
2670#endif
2671
2672 wchar_t *abs_filename;
2673 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2674 /* failed to get the absolute path of the command line filename:
2675 ignore the error, keep the relative path */
2676 return _PyStatus_OK();
2677 }
2678 if (abs_filename == NULL) {
2679 return _PyStatus_NO_MEMORY();
2680 }
2681
2682 PyMem_RawFree(config->run_filename);
2683 config->run_filename = abs_filename;
2684 return _PyStatus_OK();
2685}
2686
2687
Victor Stinner331a6a52019-05-27 16:39:22 +02002688static PyStatus
2689config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002690{
Victor Stinner331a6a52019-05-27 16:39:22 +02002691 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002692 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2693 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2694 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002695
Victor Stinnerae239f62019-05-16 17:02:56 +02002696 if (config->parse_argv < 0) {
2697 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002698 }
Victor Stinner870b0352019-05-17 03:15:12 +02002699
Victor Stinnerfed02e12019-05-17 11:12:09 +02002700 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002701 status = config_init_program_name(config);
2702 if (_PyStatus_EXCEPTION(status)) {
2703 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002704 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002705 }
Victor Stinner2f549082019-03-29 15:13:46 +01002706
Victor Stinnerdc42af82020-11-05 18:58:07 +01002707 if (config->parse_argv == 1) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002708 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002709 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2710 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002711 goto done;
2712 }
2713
Victor Stinner3939c322019-06-25 15:02:43 +02002714 status = config_run_filename_abspath(config);
2715 if (_PyStatus_EXCEPTION(status)) {
2716 goto done;
2717 }
2718
Victor Stinner331a6a52019-05-27 16:39:22 +02002719 status = config_update_argv(config, opt_index);
2720 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002721 goto done;
2722 }
Victor Stinner2f549082019-03-29 15:13:46 +01002723 }
Victor Stinner3939c322019-06-25 15:02:43 +02002724 else {
2725 status = config_run_filename_abspath(config);
2726 if (_PyStatus_EXCEPTION(status)) {
2727 goto done;
2728 }
2729 }
Victor Stinner2f549082019-03-29 15:13:46 +01002730
Victor Stinner2f549082019-03-29 15:13:46 +01002731 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002732 status = config_init_env_warnoptions(config, &env_warnoptions);
2733 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002734 goto done;
2735 }
2736 }
2737
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002738 /* Handle early PySys_AddWarnOption() calls */
2739 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2740 if (_PyStatus_EXCEPTION(status)) {
2741 goto done;
2742 }
2743
Victor Stinner331a6a52019-05-27 16:39:22 +02002744 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002745 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002746 &env_warnoptions,
2747 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002748 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002749 goto done;
2750 }
2751
Victor Stinner331a6a52019-05-27 16:39:22 +02002752 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002753
2754done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002755 _PyWideStringList_Clear(&cmdline_warnoptions);
2756 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002757 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002758 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002759}
2760
2761
Victor Stinner331a6a52019-05-27 16:39:22 +02002762PyStatus
2763_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002764{
Victor Stinner331a6a52019-05-27 16:39:22 +02002765 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2766 if (_PyStatus_EXCEPTION(status)) {
2767 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002768 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002769
Victor Stinner5f38b842019-05-01 02:30:12 +02002770 return _PyArgv_AsWstrList(args, &config->argv);
2771}
2772
2773
Victor Stinner70005ac2019-05-02 15:25:34 -04002774/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2775 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002776PyStatus
2777PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002778{
2779 _PyArgv args = {
2780 .argc = argc,
2781 .use_bytes_argv = 1,
2782 .bytes_argv = argv,
2783 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002784 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002785}
2786
2787
Victor Stinner331a6a52019-05-27 16:39:22 +02002788PyStatus
2789PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002790{
2791 _PyArgv args = {
2792 .argc = argc,
2793 .use_bytes_argv = 0,
2794 .bytes_argv = NULL,
2795 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002796 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002797}
2798
2799
Victor Stinner36242fd2019-07-01 19:13:50 +02002800PyStatus
2801PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2802 Py_ssize_t length, wchar_t **items)
2803{
2804 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2805 if (_PyStatus_EXCEPTION(status)) {
2806 return status;
2807 }
2808
2809 PyWideStringList list2 = {.length = length, .items = items};
2810 if (_PyWideStringList_Copy(list, &list2) < 0) {
2811 return _PyStatus_NO_MEMORY();
2812 }
2813 return _PyStatus_OK();
2814}
2815
2816
Victor Stinner331a6a52019-05-27 16:39:22 +02002817/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002818
2819 * Command line arguments
2820 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002821 * Py_xxx global configuration variables
2822
2823 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002824PyStatus
Victor Stinner9e1b8282020-11-10 13:21:52 +01002825_PyConfig_Read(PyConfig *config, int compute_path_config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002826{
Victor Stinner331a6a52019-05-27 16:39:22 +02002827 PyStatus status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002828
Victor Stinner331a6a52019-05-27 16:39:22 +02002829 status = _Py_PreInitializeFromConfig(config, NULL);
2830 if (_PyStatus_EXCEPTION(status)) {
2831 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002832 }
2833
Victor Stinner331a6a52019-05-27 16:39:22 +02002834 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002835
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002836 if (config->orig_argv.length == 0
Victor Stinnere81f6e62020-06-08 18:12:59 +02002837 && !(config->argv.length == 1
2838 && wcscmp(config->argv.items[0], L"") == 0))
2839 {
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002840 if (_PyWideStringList_Copy(&config->orig_argv, &config->argv) < 0) {
Victor Stinnere81f6e62020-06-08 18:12:59 +02002841 return _PyStatus_NO_MEMORY();
2842 }
Victor Stinnercab5d072019-05-17 19:01:14 +02002843 }
2844
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002845 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002846 status = core_read_precmdline(config, &precmdline);
2847 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002848 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002849 }
2850
Victor Stinner870b0352019-05-17 03:15:12 +02002851 assert(config->isolated >= 0);
2852 if (config->isolated) {
2853 config->use_environment = 0;
2854 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002855 }
2856
Victor Stinner331a6a52019-05-27 16:39:22 +02002857 status = config_read_cmdline(config);
2858 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002859 goto done;
2860 }
2861
Victor Stinner120b7072019-08-23 18:03:08 +01002862 /* Handle early PySys_AddXOption() calls */
2863 status = _PySys_ReadPreinitXOptions(config);
2864 if (_PyStatus_EXCEPTION(status)) {
2865 goto done;
2866 }
2867
Victor Stinner9e1b8282020-11-10 13:21:52 +01002868 status = config_read(config, compute_path_config);
Victor Stinner331a6a52019-05-27 16:39:22 +02002869 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002870 goto done;
2871 }
2872
Victor Stinnerf3cb8142020-11-05 18:12:33 +01002873 assert(config_check_consistency(config));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002874
Victor Stinner331a6a52019-05-27 16:39:22 +02002875 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002876
2877done:
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002878 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002879 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002880}
Victor Stinner1075d162019-03-25 23:19:57 +01002881
2882
Victor Stinner9e1b8282020-11-10 13:21:52 +01002883PyStatus
2884PyConfig_Read(PyConfig *config)
2885{
2886 return _PyConfig_Read(config, 1);
2887}
2888
2889
Victor Stinner1075d162019-03-25 23:19:57 +01002890PyObject*
2891_Py_GetConfigsAsDict(void)
2892{
Victor Stinner331a6a52019-05-27 16:39:22 +02002893 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002894 PyObject *dict = NULL;
2895
Victor Stinner331a6a52019-05-27 16:39:22 +02002896 result = PyDict_New();
2897 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002898 goto error;
2899 }
2900
Victor Stinner331a6a52019-05-27 16:39:22 +02002901 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002902 dict = _Py_GetGlobalVariablesAsDict();
2903 if (dict == NULL) {
2904 goto error;
2905 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002906 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002907 goto error;
2908 }
2909 Py_CLEAR(dict);
2910
2911 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002912 PyThreadState *tstate = _PyThreadState_GET();
2913 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002914 dict = _PyPreConfig_AsDict(pre_config);
2915 if (dict == NULL) {
2916 goto error;
2917 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002918 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002919 goto error;
2920 }
2921 Py_CLEAR(dict);
2922
2923 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002924 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerf3cb8142020-11-05 18:12:33 +01002925 dict = _PyConfig_AsDict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002926 if (dict == NULL) {
2927 goto error;
2928 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002929 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002930 goto error;
2931 }
2932 Py_CLEAR(dict);
2933
Victor Stinner8f427482020-07-08 00:20:37 +02002934 /* path config */
2935 dict = _PyPathConfig_AsDict();
2936 if (dict == NULL) {
2937 goto error;
2938 }
2939 if (PyDict_SetItemString(result, "path_config", dict) < 0) {
2940 goto error;
2941 }
2942 Py_CLEAR(dict);
2943
Victor Stinner331a6a52019-05-27 16:39:22 +02002944 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002945
2946error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002947 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002948 Py_XDECREF(dict);
2949 return NULL;
2950}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002951
2952
2953static void
2954init_dump_ascii_wstr(const wchar_t *str)
2955{
2956 if (str == NULL) {
2957 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002958 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002959 }
2960
2961 PySys_WriteStderr("'");
2962 for (; *str != L'\0'; str++) {
Victor Stinner640e8e12020-09-09 12:07:17 +02002963 unsigned int ch = (unsigned int)*str;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002964 if (ch == L'\'') {
2965 PySys_WriteStderr("\\'");
2966 } else if (0x20 <= ch && ch < 0x7f) {
Samuel Marksc3229482020-09-21 18:35:17 +10002967 PySys_WriteStderr("%c", ch);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002968 }
2969 else if (ch <= 0xff) {
2970 PySys_WriteStderr("\\x%02x", ch);
2971 }
2972#if SIZEOF_WCHAR_T > 2
2973 else if (ch > 0xffff) {
2974 PySys_WriteStderr("\\U%08x", ch);
2975 }
2976#endif
2977 else {
2978 PySys_WriteStderr("\\u%04x", ch);
2979 }
2980 }
2981 PySys_WriteStderr("'");
2982}
2983
2984
2985/* Dump the Python path configuration into sys.stderr */
2986void
2987_Py_DumpPathConfig(PyThreadState *tstate)
2988{
2989 PyObject *exc_type, *exc_value, *exc_tb;
2990 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2991
2992 PySys_WriteStderr("Python path configuration:\n");
2993
2994#define DUMP_CONFIG(NAME, FIELD) \
2995 do { \
2996 PySys_WriteStderr(" " NAME " = "); \
2997 init_dump_ascii_wstr(config->FIELD); \
2998 PySys_WriteStderr("\n"); \
2999 } while (0)
3000
Victor Stinnerda7933e2020-04-13 03:04:28 +02003001 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02003002 DUMP_CONFIG("PYTHONHOME", home);
3003 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
3004 DUMP_CONFIG("program name", program_name);
3005 PySys_WriteStderr(" isolated = %i\n", config->isolated);
3006 PySys_WriteStderr(" environment = %i\n", config->use_environment);
3007 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
3008 PySys_WriteStderr(" import site = %i\n", config->site_import);
3009#undef DUMP_CONFIG
3010
3011#define DUMP_SYS(NAME) \
3012 do { \
3013 obj = PySys_GetObject(#NAME); \
3014 PySys_FormatStderr(" sys.%s = ", #NAME); \
3015 if (obj != NULL) { \
3016 PySys_FormatStderr("%A", obj); \
3017 } \
3018 else { \
3019 PySys_WriteStderr("(not set)"); \
3020 } \
3021 PySys_FormatStderr("\n"); \
3022 } while (0)
3023
3024 PyObject *obj;
3025 DUMP_SYS(_base_executable);
3026 DUMP_SYS(base_prefix);
3027 DUMP_SYS(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +02003028 DUMP_SYS(platlibdir);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02003029 DUMP_SYS(executable);
3030 DUMP_SYS(prefix);
3031 DUMP_SYS(exec_prefix);
3032#undef DUMP_SYS
3033
3034 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
3035 if (sys_path != NULL && PyList_Check(sys_path)) {
3036 PySys_WriteStderr(" sys.path = [\n");
3037 Py_ssize_t len = PyList_GET_SIZE(sys_path);
3038 for (Py_ssize_t i=0; i < len; i++) {
3039 PyObject *path = PyList_GET_ITEM(sys_path, i);
3040 PySys_FormatStderr(" %A,\n", path);
3041 }
3042 PySys_WriteStderr(" ]\n");
3043 }
3044
3045 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
3046}