blob: 86285c77e2307c045c7d541777ac73ad35804415 [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 Stinnerdfe0dc72018-08-29 11:47:29 +020014#ifdef HAVE_LANGINFO_H
Victor Stinnere5014be2020-04-14 17:52:15 +020015# include <langinfo.h> // nl_langinfo(CODESET)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020016#endif
Victor Stinner95e2cbf2019-03-01 16:25:19 +010017#if defined(MS_WINDOWS) || defined(__CYGWIN__)
Victor Stinnere5014be2020-04-14 17:52:15 +020018# include <windows.h> // GetACP()
Victor Stinner95e2cbf2019-03-01 16:25:19 +010019# ifdef HAVE_IO_H
20# include <io.h>
21# endif
22# ifdef HAVE_FCNTL_H
Victor Stinnere5014be2020-04-14 17:52:15 +020023# include <fcntl.h> // O_BINARY
Victor Stinner95e2cbf2019-03-01 16:25:19 +010024# endif
Victor Stinnerb2457ef2018-08-29 13:25:36 +020025#endif
26
Sandro Mani8f023a22020-06-08 17:28:11 +020027#ifndef PLATLIBDIR
28# error "PLATLIBDIR macro must be defined"
29#endif
30
Victor Stinner6c785c02018-08-01 17:56:14 +020031
Victor Stinner95e2cbf2019-03-01 16:25:19 +010032/* --- Command line options --------------------------------------- */
33
Victor Stinner95e2cbf2019-03-01 16:25:19 +010034/* Short usage message (with %s for argv0) */
35static const char usage_line[] =
36"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
37
38/* Long usage message, split into parts < 512 bytes */
39static const char usage_1[] = "\
40Options and arguments (and corresponding environment variables):\n\
41-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
42 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
43-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
44-c cmd : program passed in as string (terminates option list)\n\
45-d : debug output from parser; also PYTHONDEBUG=x\n\
46-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
47-h : print this help message and exit (also --help)\n\
48";
49static const char usage_2[] = "\
50-i : inspect interactively after running script; forces a prompt even\n\
51 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
52-I : isolate Python from the user's environment (implies -E and -s)\n\
53-m mod : run library module as a script (terminates option list)\n\
54-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
55 .pyc extension; also PYTHONOPTIMIZE=x\n\
56-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
57 .pyc extension\n\
58-q : don't print version and copyright messages on interactive startup\n\
59-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
60-S : don't imply 'import site' on initialization\n\
61";
62static const char usage_3[] = "\
63-u : force the stdout and stderr streams to be unbuffered;\n\
64 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
65-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
66 can be supplied multiple times to increase verbosity\n\
67-V : print the Python version number and exit (also --version)\n\
68 when given twice, print more information about the build\n\
69-W arg : warning control; arg is action:message:category:module:lineno\n\
70 also PYTHONWARNINGS=arg\n\
71-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000072-X opt : set implementation-specific option. The following options are available:\n\
73\n\
74 -X faulthandler: enable faulthandler\n\
75 -X showrefcount: output the total reference count and number of used\n\
76 memory blocks when the program finishes or after each statement in the\n\
77 interactive interpreter. This only works on debug builds\n\
78 -X tracemalloc: start tracing Python memory allocations using the\n\
79 tracemalloc module. By default, only the most recent frame is stored in a\n\
80 traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\
81 traceback limit of NFRAME frames\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000082 -X importtime: show how long each import takes. It shows module name,\n\
83 cumulative time (including nested imports) and self time (excluding\n\
84 nested imports). Note that its output may be broken in multi-threaded\n\
85 application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
86 -X dev: enable CPythons development mode”, introducing additional runtime\n\
87 checks which are too expensive to be enabled by default. Effect of the\n\
88 developer mode:\n\
89 * Add default warning filter, as -W default\n\
90 * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\
91 * Enable the faulthandler module to dump the Python traceback on a crash\n\
92 * Enable asyncio debug mode\n\
93 * Set the dev_mode attribute of sys.flags to True\n\
94 * io.IOBase destructor logs close() exceptions\n\
95 -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\
96 locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\
97 otherwise activate automatically)\n\
98 -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
99 given directory instead of to the code tree\n\
100\n\
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100101--check-hash-based-pycs always|default|never:\n\
102 control how Python invalidates hash-based .pyc files\n\
103";
104static const char usage_4[] = "\
105file : program read from script file\n\
106- : program read from stdin (default; interactive mode if a tty)\n\
107arg ...: arguments passed to program in sys.argv[1:]\n\n\
108Other environment variables:\n\
109PYTHONSTARTUP: file executed on interactive startup (no default)\n\
110PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
111 default module search path. The result is sys.path.\n\
112";
113static const char usage_5[] =
114"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
115" The default module search path uses %s.\n"
Sandro Mani8f023a22020-06-08 17:28:11 +0200116"PYTHONPLATLIBDIR : override sys.platlibdir.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100117"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
Inada Naoki95826c72019-12-14 14:27:32 +0900118"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100119"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
120"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
121static const char usage_6[] =
122"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Serhiy Storchakae9c90aa2019-08-24 12:49:27 +0300123" to seed the hashes of str and bytes objects. It can also be set to an\n"
124" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100125" predictable seed.\n"
126"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
127" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
128" hooks.\n"
129"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
130" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
131" locale coercion and locale compatibility warnings on stderr.\n"
132"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
133" debugger. It can be set to the callable of your debugger of choice.\n"
134"PYTHONDEVMODE: enable the development mode.\n"
135"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
136
137#if defined(MS_WINDOWS)
138# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
139#else
140# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
141#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200142
143
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100144/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200145
Victor Stinner6c785c02018-08-01 17:56:14 +0200146/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200147 stdin and stdout error handler to "surrogateescape". */
148int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200149int Py_DebugFlag = 0; /* Needed by parser.c */
150int Py_VerboseFlag = 0; /* Needed by import.c */
151int Py_QuietFlag = 0; /* Needed by sysmodule.c */
152int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
153int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
154int Py_OptimizeFlag = 0; /* Needed by compile.c */
155int Py_NoSiteFlag = 0; /* Suppress 'import site' */
156int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
157int Py_FrozenFlag = 0; /* Needed by getpath.c */
158int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
159int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
160int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
161int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
162int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
163int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
164#ifdef MS_WINDOWS
165int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
166int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
167#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200168
169
Victor Stinner1075d162019-03-25 23:19:57 +0100170static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100171_Py_GetGlobalVariablesAsDict(void)
172{
173 PyObject *dict, *obj;
174
175 dict = PyDict_New();
176 if (dict == NULL) {
177 return NULL;
178 }
179
180#define SET_ITEM(KEY, EXPR) \
181 do { \
182 obj = (EXPR); \
183 if (obj == NULL) { \
184 return NULL; \
185 } \
186 int res = PyDict_SetItemString(dict, (KEY), obj); \
187 Py_DECREF(obj); \
188 if (res < 0) { \
189 goto fail; \
190 } \
191 } while (0)
192#define SET_ITEM_INT(VAR) \
193 SET_ITEM(#VAR, PyLong_FromLong(VAR))
194#define FROM_STRING(STR) \
195 ((STR != NULL) ? \
196 PyUnicode_FromString(STR) \
197 : (Py_INCREF(Py_None), Py_None))
198#define SET_ITEM_STR(VAR) \
199 SET_ITEM(#VAR, FROM_STRING(VAR))
200
201 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
202 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
203 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
204 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
205
206 SET_ITEM_INT(Py_UTF8Mode);
207 SET_ITEM_INT(Py_DebugFlag);
208 SET_ITEM_INT(Py_VerboseFlag);
209 SET_ITEM_INT(Py_QuietFlag);
210 SET_ITEM_INT(Py_InteractiveFlag);
211 SET_ITEM_INT(Py_InspectFlag);
212
213 SET_ITEM_INT(Py_OptimizeFlag);
214 SET_ITEM_INT(Py_NoSiteFlag);
215 SET_ITEM_INT(Py_BytesWarningFlag);
216 SET_ITEM_INT(Py_FrozenFlag);
217 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
218 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
219 SET_ITEM_INT(Py_NoUserSiteDirectory);
220 SET_ITEM_INT(Py_UnbufferedStdioFlag);
221 SET_ITEM_INT(Py_HashRandomizationFlag);
222 SET_ITEM_INT(Py_IsolatedFlag);
223
224#ifdef MS_WINDOWS
225 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
226 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
227#endif
228
229 return dict;
230
231fail:
232 Py_DECREF(dict);
233 return NULL;
234
235#undef FROM_STRING
236#undef SET_ITEM
237#undef SET_ITEM_INT
238#undef SET_ITEM_STR
239}
240
241
Victor Stinner331a6a52019-05-27 16:39:22 +0200242/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200243
Victor Stinner331a6a52019-05-27 16:39:22 +0200244PyStatus PyStatus_Ok(void)
245{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200246
Victor Stinner331a6a52019-05-27 16:39:22 +0200247PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200248{
Victor Stinner331a6a52019-05-27 16:39:22 +0200249 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner871ff772019-05-17 23:54:00 +0200250 .err_msg = err_msg};
251}
252
Victor Stinner331a6a52019-05-27 16:39:22 +0200253PyStatus PyStatus_NoMemory(void)
254{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200255
Victor Stinner331a6a52019-05-27 16:39:22 +0200256PyStatus PyStatus_Exit(int exitcode)
257{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200258
259
Victor Stinner331a6a52019-05-27 16:39:22 +0200260int PyStatus_IsError(PyStatus status)
261{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200262
Victor Stinner331a6a52019-05-27 16:39:22 +0200263int PyStatus_IsExit(PyStatus status)
264{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200265
Victor Stinner331a6a52019-05-27 16:39:22 +0200266int PyStatus_Exception(PyStatus status)
267{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200268
269
Victor Stinner331a6a52019-05-27 16:39:22 +0200270/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100271
272#ifndef NDEBUG
273int
Victor Stinner331a6a52019-05-27 16:39:22 +0200274_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100275{
276 assert(list->length >= 0);
277 if (list->length != 0) {
278 assert(list->items != NULL);
279 }
280 for (Py_ssize_t i = 0; i < list->length; i++) {
281 assert(list->items[i] != NULL);
282 }
283 return 1;
284}
285#endif /* Py_DEBUG */
286
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100287
Victor Stinner6c785c02018-08-01 17:56:14 +0200288void
Victor Stinner331a6a52019-05-27 16:39:22 +0200289_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200290{
Victor Stinner331a6a52019-05-27 16:39:22 +0200291 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100292 for (Py_ssize_t i=0; i < list->length; i++) {
293 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200294 }
Victor Stinner74f65682019-03-15 15:08:05 +0100295 PyMem_RawFree(list->items);
296 list->length = 0;
297 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200298}
299
300
Victor Stinner74f65682019-03-15 15:08:05 +0100301int
Victor Stinner331a6a52019-05-27 16:39:22 +0200302_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200303{
Victor Stinner331a6a52019-05-27 16:39:22 +0200304 assert(_PyWideStringList_CheckConsistency(list));
305 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100306
307 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200308 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100309 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300310 }
Victor Stinner74f65682019-03-15 15:08:05 +0100311
Victor Stinnerfb4ae152019-09-30 01:40:17 +0200312 PyWideStringList copy = _PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100313
314 size_t size = list2->length * sizeof(list2->items[0]);
315 copy.items = PyMem_RawMalloc(size);
316 if (copy.items == NULL) {
317 return -1;
318 }
319
320 for (Py_ssize_t i=0; i < list2->length; i++) {
321 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
322 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200323 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100324 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200325 }
Victor Stinner74f65682019-03-15 15:08:05 +0100326 copy.items[i] = item;
327 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200328 }
Victor Stinner74f65682019-03-15 15:08:05 +0100329
Victor Stinner331a6a52019-05-27 16:39:22 +0200330 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100331 *list = copy;
332 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200333}
334
335
Victor Stinner331a6a52019-05-27 16:39:22 +0200336PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100337PyWideStringList_Insert(PyWideStringList *list,
338 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100339{
Victor Stinner3842f292019-08-23 16:57:54 +0100340 Py_ssize_t len = list->length;
341 if (len == PY_SSIZE_T_MAX) {
Min ho Kim96e12d52019-07-22 06:12:33 +1000342 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200343 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100344 }
Victor Stinner3842f292019-08-23 16:57:54 +0100345 if (index < 0) {
346 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
347 }
348 if (index > len) {
349 index = len;
350 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100351
Victor Stinner74f65682019-03-15 15:08:05 +0100352 wchar_t *item2 = _PyMem_RawWcsdup(item);
353 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200354 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100355 }
Victor Stinner74f65682019-03-15 15:08:05 +0100356
Victor Stinner3842f292019-08-23 16:57:54 +0100357 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100358 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
359 if (items2 == NULL) {
360 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200361 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100362 }
363
Victor Stinner3842f292019-08-23 16:57:54 +0100364 if (index < len) {
365 memmove(&items2[index + 1],
366 &items2[index],
367 (len - index) * sizeof(items2[0]));
368 }
369
370 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100371 list->items = items2;
372 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200373 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100374}
375
376
Victor Stinner331a6a52019-05-27 16:39:22 +0200377PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100378PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
379{
380 return PyWideStringList_Insert(list, list->length, item);
381}
382
383
384PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200385_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100386{
387 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200388 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
389 if (_PyStatus_EXCEPTION(status)) {
390 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100391 }
392 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200393 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100394}
395
396
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100397static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200398_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100399{
400 for (Py_ssize_t i = 0; i < list->length; i++) {
401 if (wcscmp(list->items[i], item) == 0) {
402 return 1;
403 }
404 }
405 return 0;
406}
407
408
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100409PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200410_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100411{
Victor Stinner331a6a52019-05-27 16:39:22 +0200412 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100413
Victor Stinner74f65682019-03-15 15:08:05 +0100414 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100415 if (pylist == NULL) {
416 return NULL;
417 }
418
Victor Stinner74f65682019-03-15 15:08:05 +0100419 for (Py_ssize_t i = 0; i < list->length; i++) {
420 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
421 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100422 Py_DECREF(pylist);
423 return NULL;
424 }
Victor Stinner74f65682019-03-15 15:08:05 +0100425 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100426 }
427 return pylist;
428}
429
430
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100431/* --- Py_SetStandardStreamEncoding() ----------------------------- */
432
Victor Stinner124b9eb2018-08-29 01:29:06 +0200433/* Helper to allow an embedding application to override the normal
434 * mechanism that attempts to figure out an appropriate IO encoding
435 */
436
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200437static char *_Py_StandardStreamEncoding = NULL;
438static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200439
440int
441Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
442{
443 if (Py_IsInitialized()) {
444 /* This is too late to have any effect */
445 return -1;
446 }
447
448 int res = 0;
449
450 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
451 but Py_Initialize() can change the allocator. Use a known allocator
452 to be able to release the memory later. */
453 PyMemAllocatorEx old_alloc;
454 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
455
456 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
457 * initialised yet.
458 *
459 * However, the raw memory allocators are initialised appropriately
460 * as C static variables, so _PyMem_RawStrdup is OK even though
461 * Py_Initialize hasn't been called yet.
462 */
463 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200464 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200465 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
466 if (!_Py_StandardStreamEncoding) {
467 res = -2;
468 goto done;
469 }
470 }
471 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200472 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200473 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
474 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200475 PyMem_RawFree(_Py_StandardStreamEncoding);
476 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200477 res = -3;
478 goto done;
479 }
480 }
481#ifdef MS_WINDOWS
482 if (_Py_StandardStreamEncoding) {
483 /* Overriding the stream encoding implies legacy streams */
484 Py_LegacyWindowsStdioFlag = 1;
485 }
486#endif
487
488done:
489 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
490
491 return res;
492}
493
494
495void
496_Py_ClearStandardStreamEncoding(void)
497{
498 /* Use the same allocator than Py_SetStandardStreamEncoding() */
499 PyMemAllocatorEx old_alloc;
500 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
501
502 /* We won't need them anymore. */
503 if (_Py_StandardStreamEncoding) {
504 PyMem_RawFree(_Py_StandardStreamEncoding);
505 _Py_StandardStreamEncoding = NULL;
506 }
507 if (_Py_StandardStreamErrors) {
508 PyMem_RawFree(_Py_StandardStreamErrors);
509 _Py_StandardStreamErrors = NULL;
510 }
511
512 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
513}
514
515
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100516/* --- Py_GetArgcArgv() ------------------------------------------- */
517
518/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200519static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100520
521
522void
523_Py_ClearArgcArgv(void)
524{
525 PyMemAllocatorEx old_alloc;
526 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
527
Victor Stinner331a6a52019-05-27 16:39:22 +0200528 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100529
530 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
531}
532
533
Victor Stinner4fffd382019-03-06 01:44:31 +0100534static int
Victor Stinner74f65682019-03-15 15:08:05 +0100535_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100536{
Victor Stinner331a6a52019-05-27 16:39:22 +0200537 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100538 int res;
539
540 PyMemAllocatorEx old_alloc;
541 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
542
Victor Stinner331a6a52019-05-27 16:39:22 +0200543 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100544
545 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
546 return res;
547}
548
549
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100550void
551Py_GetArgcArgv(int *argc, wchar_t ***argv)
552{
Victor Stinner74f65682019-03-15 15:08:05 +0100553 *argc = (int)orig_argv.length;
554 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100555}
556
557
Victor Stinner331a6a52019-05-27 16:39:22 +0200558/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100559
560#define DECODE_LOCALE_ERR(NAME, LEN) \
561 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200562 ? _PyStatus_ERR("cannot decode " NAME) \
563 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100564
Victor Stinner441b10c2019-09-28 04:28:35 +0200565
Victor Stinner6c785c02018-08-01 17:56:14 +0200566/* Free memory allocated in config, but don't clear all attributes */
567void
Victor Stinner331a6a52019-05-27 16:39:22 +0200568PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200569{
570#define CLEAR(ATTR) \
571 do { \
572 PyMem_RawFree(ATTR); \
573 ATTR = NULL; \
574 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200575
576 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200577 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200578 CLEAR(config->home);
579 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200580
Victor Stinner331a6a52019-05-27 16:39:22 +0200581 _PyWideStringList_Clear(&config->argv);
582 _PyWideStringList_Clear(&config->warnoptions);
583 _PyWideStringList_Clear(&config->xoptions);
584 _PyWideStringList_Clear(&config->module_search_paths);
585 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200586
587 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700588 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200589 CLEAR(config->prefix);
590 CLEAR(config->base_prefix);
591 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200592 CLEAR(config->base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200593 CLEAR(config->platlibdir);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200594
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200595 CLEAR(config->filesystem_encoding);
596 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200597 CLEAR(config->stdio_encoding);
598 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100599 CLEAR(config->run_command);
600 CLEAR(config->run_module);
601 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400602 CLEAR(config->check_hash_pycs_mode);
Victor Stinnere2d47a02020-06-15 16:27:47 +0200603
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200604 _PyWideStringList_Clear(&config->orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200605#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200606}
607
608
Victor Stinner8462a492019-10-01 12:06:16 +0200609void
Victor Stinner331a6a52019-05-27 16:39:22 +0200610_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200611{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200612 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200613
Victor Stinner022be022019-05-22 23:58:50 +0200614 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200615 config->isolated = -1;
616 config->use_environment = -1;
617 config->dev_mode = -1;
618 config->install_signal_handlers = 1;
619 config->use_hash_seed = -1;
620 config->faulthandler = -1;
621 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200622 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200623 config->parse_argv = 0;
624 config->site_import = -1;
625 config->bytes_warning = -1;
626 config->inspect = -1;
627 config->interactive = -1;
628 config->optimization_level = -1;
629 config->parser_debug= -1;
630 config->write_bytecode = -1;
631 config->verbose = -1;
632 config->quiet = -1;
633 config->user_site_directory = -1;
634 config->configure_c_stdio = 0;
635 config->buffered_stdio = -1;
636 config->_install_importlib = 1;
637 config->check_hash_pycs_mode = NULL;
638 config->pathconfig_warnings = -1;
639 config->_init_main = 1;
Victor Stinner252346a2020-05-01 11:33:44 +0200640 config->_isolated_interpreter = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200641#ifdef MS_WINDOWS
642 config->legacy_windows_stdio = -1;
643#endif
644}
645
646
Victor Stinner8462a492019-10-01 12:06:16 +0200647static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200648config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200649{
Victor Stinner8462a492019-10-01 12:06:16 +0200650 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200651
652 config->isolated = 0;
653 config->use_environment = 1;
654 config->site_import = 1;
655 config->bytes_warning = 0;
656 config->inspect = 0;
657 config->interactive = 0;
658 config->optimization_level = 0;
659 config->parser_debug= 0;
660 config->write_bytecode = 1;
661 config->verbose = 0;
662 config->quiet = 0;
663 config->user_site_directory = 1;
664 config->buffered_stdio = 1;
665 config->pathconfig_warnings = 1;
666#ifdef MS_WINDOWS
667 config->legacy_windows_stdio = 0;
668#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200669}
670
671
Victor Stinner8462a492019-10-01 12:06:16 +0200672void
Victor Stinner331a6a52019-05-27 16:39:22 +0200673PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200674{
Victor Stinner8462a492019-10-01 12:06:16 +0200675 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200676
Victor Stinner022be022019-05-22 23:58:50 +0200677 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200678 config->configure_c_stdio = 1;
679 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200680}
681
682
Victor Stinner8462a492019-10-01 12:06:16 +0200683void
Victor Stinner331a6a52019-05-27 16:39:22 +0200684PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200685{
Victor Stinner8462a492019-10-01 12:06:16 +0200686 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200687
Victor Stinner022be022019-05-22 23:58:50 +0200688 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200689 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200690 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200691 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200692 config->dev_mode = 0;
693 config->install_signal_handlers = 0;
694 config->use_hash_seed = 0;
695 config->faulthandler = 0;
696 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200697 config->pathconfig_warnings = 0;
698#ifdef MS_WINDOWS
699 config->legacy_windows_stdio = 0;
700#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200701}
702
703
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200704/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200705PyStatus
706PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200707{
Victor Stinner331a6a52019-05-27 16:39:22 +0200708 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
709 if (_PyStatus_EXCEPTION(status)) {
710 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200711 }
712
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200713 wchar_t *str2;
714 if (str != NULL) {
715 str2 = _PyMem_RawWcsdup(str);
716 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200717 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200718 }
719 }
720 else {
721 str2 = NULL;
722 }
723 PyMem_RawFree(*config_str);
724 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200725 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200726}
727
728
Victor Stinner331a6a52019-05-27 16:39:22 +0200729static PyStatus
730config_set_bytes_string(PyConfig *config, wchar_t **config_str,
731 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200732{
Victor Stinner331a6a52019-05-27 16:39:22 +0200733 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
734 if (_PyStatus_EXCEPTION(status)) {
735 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400736 }
737
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200738 wchar_t *str2;
739 if (str != NULL) {
740 size_t len;
741 str2 = Py_DecodeLocale(str, &len);
742 if (str2 == NULL) {
743 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200744 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200745 }
746 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200747 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200748 }
749 }
750 }
751 else {
752 str2 = NULL;
753 }
754 PyMem_RawFree(*config_str);
755 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200756 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200757}
758
759
Victor Stinner331a6a52019-05-27 16:39:22 +0200760#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
761 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400762
763
Victor Stinner70005ac2019-05-02 15:25:34 -0400764/* Decode str using Py_DecodeLocale() and set the result into *config_str.
765 Pre-initialize Python if needed to ensure that encodings are properly
766 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200767PyStatus
768PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200769 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400770{
Victor Stinner331a6a52019-05-27 16:39:22 +0200771 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400772}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200773
774
Victor Stinner331a6a52019-05-27 16:39:22 +0200775PyStatus
776_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200777{
Victor Stinner331a6a52019-05-27 16:39:22 +0200778 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200779
Victor Stinner331a6a52019-05-27 16:39:22 +0200780 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200781
782#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200783#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200784 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200785 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
786 if (_PyStatus_EXCEPTION(status)) { \
787 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200788 } \
789 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100790#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200791 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200792 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200793 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200794 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200795 } while (0)
796
Victor Stinner6d1c4672019-05-20 11:02:00 +0200797 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100798 COPY_ATTR(isolated);
799 COPY_ATTR(use_environment);
800 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200801 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200802 COPY_ATTR(use_hash_seed);
803 COPY_ATTR(hash_seed);
804 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200805 COPY_ATTR(faulthandler);
806 COPY_ATTR(tracemalloc);
807 COPY_ATTR(import_time);
808 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200809 COPY_ATTR(dump_refs);
810 COPY_ATTR(malloc_stats);
811
Victor Stinner124b9eb2018-08-29 01:29:06 +0200812 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200813 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200814 COPY_WSTR_ATTR(home);
815 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200816
Victor Stinnerae239f62019-05-16 17:02:56 +0200817 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100818 COPY_WSTRLIST(argv);
819 COPY_WSTRLIST(warnoptions);
820 COPY_WSTRLIST(xoptions);
821 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200822 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200823
Victor Stinner124b9eb2018-08-29 01:29:06 +0200824 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700825 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200826 COPY_WSTR_ATTR(prefix);
827 COPY_WSTR_ATTR(base_prefix);
828 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200829 COPY_WSTR_ATTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200830 COPY_WSTR_ATTR(platlibdir);
Victor Stinner6c785c02018-08-01 17:56:14 +0200831
Victor Stinner6c785c02018-08-01 17:56:14 +0200832 COPY_ATTR(site_import);
833 COPY_ATTR(bytes_warning);
834 COPY_ATTR(inspect);
835 COPY_ATTR(interactive);
836 COPY_ATTR(optimization_level);
837 COPY_ATTR(parser_debug);
838 COPY_ATTR(write_bytecode);
839 COPY_ATTR(verbose);
840 COPY_ATTR(quiet);
841 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200842 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200843 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400844 COPY_WSTR_ATTR(filesystem_encoding);
845 COPY_WSTR_ATTR(filesystem_errors);
846 COPY_WSTR_ATTR(stdio_encoding);
847 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200848#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200849 COPY_ATTR(legacy_windows_stdio);
850#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100851 COPY_ATTR(skip_source_first_line);
852 COPY_WSTR_ATTR(run_command);
853 COPY_WSTR_ATTR(run_module);
854 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400855 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200856 COPY_ATTR(pathconfig_warnings);
857 COPY_ATTR(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200858 COPY_ATTR(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200859 COPY_WSTRLIST(orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200860
861#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200862#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200863#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200864 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200865}
866
867
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100868static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200869config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100870{
871 PyObject *dict;
872
873 dict = PyDict_New();
874 if (dict == NULL) {
875 return NULL;
876 }
877
878#define SET_ITEM(KEY, EXPR) \
879 do { \
880 PyObject *obj = (EXPR); \
881 if (obj == NULL) { \
882 goto fail; \
883 } \
884 int res = PyDict_SetItemString(dict, (KEY), obj); \
885 Py_DECREF(obj); \
886 if (res < 0) { \
887 goto fail; \
888 } \
889 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100890#define SET_ITEM_INT(ATTR) \
891 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
892#define SET_ITEM_UINT(ATTR) \
893 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100894#define FROM_WSTRING(STR) \
895 ((STR != NULL) ? \
896 PyUnicode_FromWideChar(STR, -1) \
897 : (Py_INCREF(Py_None), Py_None))
898#define SET_ITEM_WSTR(ATTR) \
899 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
900#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200901 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100902
Victor Stinner6d1c4672019-05-20 11:02:00 +0200903 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100904 SET_ITEM_INT(isolated);
905 SET_ITEM_INT(use_environment);
906 SET_ITEM_INT(dev_mode);
907 SET_ITEM_INT(install_signal_handlers);
908 SET_ITEM_INT(use_hash_seed);
909 SET_ITEM_UINT(hash_seed);
910 SET_ITEM_INT(faulthandler);
911 SET_ITEM_INT(tracemalloc);
912 SET_ITEM_INT(import_time);
913 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100914 SET_ITEM_INT(dump_refs);
915 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400916 SET_ITEM_WSTR(filesystem_encoding);
917 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100918 SET_ITEM_WSTR(pycache_prefix);
919 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200920 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100921 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100922 SET_ITEM_WSTRLIST(xoptions);
923 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200924 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100925 SET_ITEM_WSTR(home);
926 SET_ITEM_WSTRLIST(module_search_paths);
927 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700928 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100929 SET_ITEM_WSTR(prefix);
930 SET_ITEM_WSTR(base_prefix);
931 SET_ITEM_WSTR(exec_prefix);
932 SET_ITEM_WSTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200933 SET_ITEM_WSTR(platlibdir);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100934 SET_ITEM_INT(site_import);
935 SET_ITEM_INT(bytes_warning);
936 SET_ITEM_INT(inspect);
937 SET_ITEM_INT(interactive);
938 SET_ITEM_INT(optimization_level);
939 SET_ITEM_INT(parser_debug);
940 SET_ITEM_INT(write_bytecode);
941 SET_ITEM_INT(verbose);
942 SET_ITEM_INT(quiet);
943 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200944 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100945 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400946 SET_ITEM_WSTR(stdio_encoding);
947 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100948#ifdef MS_WINDOWS
949 SET_ITEM_INT(legacy_windows_stdio);
950#endif
951 SET_ITEM_INT(skip_source_first_line);
952 SET_ITEM_WSTR(run_command);
953 SET_ITEM_WSTR(run_module);
954 SET_ITEM_WSTR(run_filename);
955 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400956 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200957 SET_ITEM_INT(pathconfig_warnings);
958 SET_ITEM_INT(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200959 SET_ITEM_INT(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200960 SET_ITEM_WSTRLIST(orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100961
962 return dict;
963
964fail:
965 Py_DECREF(dict);
966 return NULL;
967
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100968#undef FROM_WSTRING
969#undef SET_ITEM
970#undef SET_ITEM_INT
971#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100972#undef SET_ITEM_WSTR
973#undef SET_ITEM_WSTRLIST
974}
975
976
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100977static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200978config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200979{
Victor Stinner20004952019-03-26 02:31:11 +0100980 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200981}
982
983
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100984/* Get a copy of the environment variable as wchar_t*.
985 Return 0 on success, but *dest can be NULL.
986 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200987static PyStatus
988config_get_env_dup(PyConfig *config,
989 wchar_t **dest,
990 wchar_t *wname, char *name,
991 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200992{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200993 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100994 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200995
Victor Stinner20004952019-03-26 02:31:11 +0100996 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200997 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200998 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200999 }
1000
1001#ifdef MS_WINDOWS
1002 const wchar_t *var = _wgetenv(wname);
1003 if (!var || var[0] == '\0') {
1004 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001005 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001006 }
1007
Victor Stinner331a6a52019-05-27 16:39:22 +02001008 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +02001009#else
1010 const char *var = getenv(name);
1011 if (!var || var[0] == '\0') {
1012 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001013 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001014 }
1015
Victor Stinner331a6a52019-05-27 16:39:22 +02001016 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001017#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001018}
1019
1020
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001021#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001022 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001023
1024
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001025static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001026config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001027{
Victor Stinner022be022019-05-22 23:58:50 +02001028 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1029 /* Python and Isolated configuration ignore global variables */
1030 return;
1031 }
1032
Victor Stinner6c785c02018-08-01 17:56:14 +02001033#define COPY_FLAG(ATTR, VALUE) \
1034 if (config->ATTR == -1) { \
1035 config->ATTR = VALUE; \
1036 }
1037#define COPY_NOT_FLAG(ATTR, VALUE) \
1038 if (config->ATTR == -1) { \
1039 config->ATTR = !(VALUE); \
1040 }
1041
Victor Stinner20004952019-03-26 02:31:11 +01001042 COPY_FLAG(isolated, Py_IsolatedFlag);
1043 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001044 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1045 COPY_FLAG(inspect, Py_InspectFlag);
1046 COPY_FLAG(interactive, Py_InteractiveFlag);
1047 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1048 COPY_FLAG(parser_debug, Py_DebugFlag);
1049 COPY_FLAG(verbose, Py_VerboseFlag);
1050 COPY_FLAG(quiet, Py_QuietFlag);
1051#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001052 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1053#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001054 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001055
Victor Stinner6c785c02018-08-01 17:56:14 +02001056 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1057 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1058 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1059 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1060
Victor Stinner6c785c02018-08-01 17:56:14 +02001061#undef COPY_FLAG
1062#undef COPY_NOT_FLAG
1063}
1064
1065
1066/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001067static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001068config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001069{
1070#define COPY_FLAG(ATTR, VAR) \
1071 if (config->ATTR != -1) { \
1072 VAR = config->ATTR; \
1073 }
1074#define COPY_NOT_FLAG(ATTR, VAR) \
1075 if (config->ATTR != -1) { \
1076 VAR = !config->ATTR; \
1077 }
1078
Victor Stinner20004952019-03-26 02:31:11 +01001079 COPY_FLAG(isolated, Py_IsolatedFlag);
1080 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001081 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1082 COPY_FLAG(inspect, Py_InspectFlag);
1083 COPY_FLAG(interactive, Py_InteractiveFlag);
1084 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1085 COPY_FLAG(parser_debug, Py_DebugFlag);
1086 COPY_FLAG(verbose, Py_VerboseFlag);
1087 COPY_FLAG(quiet, Py_QuietFlag);
1088#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001089 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1090#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001091 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001092
Victor Stinner6c785c02018-08-01 17:56:14 +02001093 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1094 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1095 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1096 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1097
Victor Stinner6c785c02018-08-01 17:56:14 +02001098 /* Random or non-zero hash seed */
1099 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1100 config->hash_seed != 0);
1101
1102#undef COPY_FLAG
1103#undef COPY_NOT_FLAG
1104}
1105
1106
1107/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1108 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001109static PyStatus
1110config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001111{
Victor Stinner331a6a52019-05-27 16:39:22 +02001112 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001113
Victor Stinner6c785c02018-08-01 17:56:14 +02001114 /* If Py_SetProgramName() was called, use its value */
1115 const wchar_t *program_name = _Py_path_config.program_name;
1116 if (program_name != NULL) {
1117 config->program_name = _PyMem_RawWcsdup(program_name);
1118 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001119 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001120 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001121 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001122 }
1123
1124#ifdef __APPLE__
1125 /* On MacOS X, when the Python interpreter is embedded in an
1126 application bundle, it gets executed by a bootstrapping script
1127 that does os.execve() with an argv[0] that's different from the
1128 actual Python executable. This is needed to keep the Finder happy,
1129 or rather, to work around Apple's overly strict requirements of
1130 the process name. However, we still need a usable sys.executable,
1131 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001132 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001133 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001134 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001135 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001136 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1137 "PYTHONEXECUTABLE environment variable");
1138 if (_PyStatus_EXCEPTION(status)) {
1139 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001140 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001141 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001142 }
1143#ifdef WITH_NEXT_FRAMEWORK
1144 else {
1145 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1146 if (pyvenv_launcher && *pyvenv_launcher) {
1147 /* Used by Mac/Tools/pythonw.c to forward
1148 * the argv0 of the stub executable
1149 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001150 status = CONFIG_SET_BYTES_STR(config,
1151 &config->program_name,
1152 pyvenv_launcher,
1153 "__PYVENV_LAUNCHER__ environment variable");
1154 if (_PyStatus_EXCEPTION(status)) {
1155 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001156 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001157
1158 /*
1159 * This environment variable is used to communicate between
1160 * the stub launcher and the real interpreter and isn't needed
1161 * beyond this point.
1162 *
1163 * Clean up to avoid problems when launching other programs
1164 * later on.
1165 */
1166 (void)unsetenv("__PYVENV_LAUNCHER__");
1167
Victor Stinner331a6a52019-05-27 16:39:22 +02001168 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001169 }
1170 }
1171#endif /* WITH_NEXT_FRAMEWORK */
1172#endif /* __APPLE__ */
1173
Victor Stinnerfed02e12019-05-17 11:12:09 +02001174 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001175 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001176 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1177 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1178 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001179 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001180 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001181 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001182 }
1183
Victor Stinnerfed02e12019-05-17 11:12:09 +02001184 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001185#ifdef MS_WINDOWS
1186 const wchar_t *default_program_name = L"python";
1187#else
1188 const wchar_t *default_program_name = L"python3";
1189#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001190 status = PyConfig_SetString(config, &config->program_name,
1191 default_program_name);
1192 if (_PyStatus_EXCEPTION(status)) {
1193 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001194 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001195 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001196}
1197
Victor Stinner331a6a52019-05-27 16:39:22 +02001198static PyStatus
1199config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001200{
1201 assert(config->executable == NULL);
1202
1203 /* If Py_SetProgramFullPath() was called, use its value */
1204 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1205 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001206 PyStatus status = PyConfig_SetString(config,
1207 &config->executable,
1208 program_full_path);
1209 if (_PyStatus_EXCEPTION(status)) {
1210 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001211 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001212 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001213 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001214 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001215}
Victor Stinner6c785c02018-08-01 17:56:14 +02001216
Victor Stinner4fffd382019-03-06 01:44:31 +01001217
Victor Stinner6c785c02018-08-01 17:56:14 +02001218static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001219config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001220{
Victor Stinner74f65682019-03-15 15:08:05 +01001221 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001222}
1223
1224
Victor Stinner331a6a52019-05-27 16:39:22 +02001225static PyStatus
1226config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001227{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001228 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001229
1230 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001231 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001232 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001233 PyStatus status = PyConfig_SetString(config, &config->home, home);
1234 if (_PyStatus_EXCEPTION(status)) {
1235 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001236 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001237 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001238 }
1239
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001240 return CONFIG_GET_ENV_DUP(config, &config->home,
1241 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001242}
1243
1244
Victor Stinner331a6a52019-05-27 16:39:22 +02001245static PyStatus
1246config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001247{
Victor Stinner331a6a52019-05-27 16:39:22 +02001248 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001249
1250 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1251 /* Convert a text seed to a numeric one */
1252 if (seed_text && strcmp(seed_text, "random") != 0) {
1253 const char *endptr = seed_text;
1254 unsigned long seed;
1255 errno = 0;
1256 seed = strtoul(seed_text, (char **)&endptr, 10);
1257 if (*endptr != '\0'
1258 || seed > 4294967295UL
1259 || (errno == ERANGE && seed == ULONG_MAX))
1260 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001261 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001262 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001263 }
1264 /* Use a specific hash */
1265 config->use_hash_seed = 1;
1266 config->hash_seed = seed;
1267 }
1268 else {
1269 /* Use a random hash */
1270 config->use_hash_seed = 0;
1271 config->hash_seed = 0;
1272 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001273 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001274}
1275
1276
Victor Stinner6c785c02018-08-01 17:56:14 +02001277static int
1278config_wstr_to_int(const wchar_t *wstr, int *result)
1279{
1280 const wchar_t *endptr = wstr;
1281 errno = 0;
1282 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1283 if (*endptr != '\0' || errno == ERANGE) {
1284 return -1;
1285 }
1286 if (value < INT_MIN || value > INT_MAX) {
1287 return -1;
1288 }
1289
1290 *result = (int)value;
1291 return 0;
1292}
1293
1294
Victor Stinner331a6a52019-05-27 16:39:22 +02001295static PyStatus
1296config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001297{
Victor Stinner331a6a52019-05-27 16:39:22 +02001298 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001299 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001300
Victor Stinner6c785c02018-08-01 17:56:14 +02001301 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001302 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1303 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1304 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1305 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001306
1307 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001308 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001309 if (dont_write_bytecode) {
1310 config->write_bytecode = 0;
1311 }
1312
1313 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001314 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001315 if (no_user_site_directory) {
1316 config->user_site_directory = 0;
1317 }
1318
1319 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001320 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001321 if (unbuffered_stdio) {
1322 config->buffered_stdio = 0;
1323 }
1324
1325#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001326 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001327 "PYTHONLEGACYWINDOWSSTDIO");
1328#endif
1329
Victor Stinner331a6a52019-05-27 16:39:22 +02001330 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001331 config->dump_refs = 1;
1332 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001333 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001334 config->malloc_stats = 1;
1335 }
1336
Victor Stinner331a6a52019-05-27 16:39:22 +02001337 if (config->pythonpath_env == NULL) {
1338 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1339 L"PYTHONPATH", "PYTHONPATH");
1340 if (_PyStatus_EXCEPTION(status)) {
1341 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001342 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001343 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001344
Sandro Mani8f023a22020-06-08 17:28:11 +02001345 if(config->platlibdir == NULL) {
1346 status = CONFIG_GET_ENV_DUP(config, &config->platlibdir,
1347 L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR");
1348 if (_PyStatus_EXCEPTION(status)) {
1349 return status;
1350 }
1351 }
1352
Victor Stinner6c785c02018-08-01 17:56:14 +02001353 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001354 status = config_init_hash_seed(config);
1355 if (_PyStatus_EXCEPTION(status)) {
1356 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001357 }
1358 }
1359
Victor Stinner331a6a52019-05-27 16:39:22 +02001360 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001361}
1362
1363
Victor Stinner331a6a52019-05-27 16:39:22 +02001364static PyStatus
1365config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001366{
1367 int nframe;
1368 int valid;
1369
Victor Stinner331a6a52019-05-27 16:39:22 +02001370 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001371 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001372 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001373 valid = (nframe >= 0);
1374 }
1375 else {
1376 valid = 0;
1377 }
1378 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001379 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001380 }
1381 config->tracemalloc = nframe;
1382 }
1383
1384 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1385 if (xoption) {
1386 const wchar_t *sep = wcschr(xoption, L'=');
1387 if (sep) {
1388 if (!config_wstr_to_int(sep + 1, &nframe)) {
1389 valid = (nframe >= 0);
1390 }
1391 else {
1392 valid = 0;
1393 }
1394 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001395 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1396 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001397 }
1398 }
1399 else {
1400 /* -X tracemalloc behaves as -X tracemalloc=1 */
1401 nframe = 1;
1402 }
1403 config->tracemalloc = nframe;
1404 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001405 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001406}
1407
1408
Victor Stinner331a6a52019-05-27 16:39:22 +02001409static PyStatus
1410config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001411{
1412 assert(config->pycache_prefix == NULL);
1413
1414 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1415 if (xoption) {
1416 const wchar_t *sep = wcschr(xoption, L'=');
1417 if (sep && wcslen(sep) > 1) {
1418 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1419 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001420 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001421 }
1422 }
1423 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001424 // PYTHONPYCACHEPREFIX env var ignored
1425 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001426 config->pycache_prefix = NULL;
1427 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001428 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001429 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001430
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001431 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1432 L"PYTHONPYCACHEPREFIX",
1433 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001434}
1435
1436
Victor Stinner331a6a52019-05-27 16:39:22 +02001437static PyStatus
1438config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001439{
1440 /* More complex options configured by env var and -X option */
1441 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001442 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001443 || config_get_xoption(config, L"faulthandler")) {
1444 config->faulthandler = 1;
1445 }
1446 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001447 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001448 || config_get_xoption(config, L"importtime")) {
1449 config->import_time = 1;
1450 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001451
Victor Stinner331a6a52019-05-27 16:39:22 +02001452 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001453 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001454 status = config_init_tracemalloc(config);
1455 if (_PyStatus_EXCEPTION(status)) {
1456 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001457 }
1458 }
1459
1460 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001461 status = config_init_pycache_prefix(config);
1462 if (_PyStatus_EXCEPTION(status)) {
1463 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001464 }
1465 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001466 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001467}
1468
1469
Victor Stinner709d23d2019-05-02 14:56:30 -04001470static const wchar_t *
Andy Lesteraa450a02020-03-07 11:36:04 -06001471config_get_stdio_errors(void)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001472{
1473#ifndef MS_WINDOWS
1474 const char *loc = setlocale(LC_CTYPE, NULL);
1475 if (loc != NULL) {
1476 /* surrogateescape is the default in the legacy C and POSIX locales */
1477 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001478 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001479 }
1480
1481#ifdef PY_COERCE_C_LOCALE
1482 /* surrogateescape is the default in locale coercion target locales */
1483 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001484 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001485 }
1486#endif
1487 }
1488
Victor Stinner709d23d2019-05-02 14:56:30 -04001489 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001490#else
1491 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001492 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001493#endif
1494}
1495
1496
Victor Stinner331a6a52019-05-27 16:39:22 +02001497static PyStatus
1498config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001499{
1500#ifdef MS_WINDOWS
1501 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001502 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001503 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001504#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001505 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001506#else
1507 const char *encoding = nl_langinfo(CODESET);
1508 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001509 return _PyStatus_ERR("failed to get the locale encoding: "
1510 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001511 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001512 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001513 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001514 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001515 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001516#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001517}
1518
1519
Victor Stinner331a6a52019-05-27 16:39:22 +02001520static PyStatus
1521config_init_stdio_encoding(PyConfig *config,
1522 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001523{
Victor Stinner331a6a52019-05-27 16:39:22 +02001524 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001525
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001526 /* If Py_SetStandardStreamEncoding() have been called, use these
1527 parameters. */
1528 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001529 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1530 _Py_StandardStreamEncoding,
1531 "_Py_StandardStreamEncoding");
1532 if (_PyStatus_EXCEPTION(status)) {
1533 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001534 }
1535 }
1536
1537 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001538 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1539 _Py_StandardStreamErrors,
1540 "_Py_StandardStreamErrors");
1541 if (_PyStatus_EXCEPTION(status)) {
1542 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001543 }
1544 }
1545
1546 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001547 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001548 }
1549
1550 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001551 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001552 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001553 char *pythonioencoding = _PyMem_RawStrdup(opt);
1554 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001555 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001556 }
1557
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001558 char *errors = strchr(pythonioencoding, ':');
1559 if (errors) {
1560 *errors = '\0';
1561 errors++;
1562 if (!errors[0]) {
1563 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001564 }
1565 }
1566
1567 /* Does PYTHONIOENCODING contain an encoding? */
1568 if (pythonioencoding[0]) {
1569 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001570 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1571 pythonioencoding,
1572 "PYTHONIOENCODING environment variable");
1573 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001574 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001575 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001576 }
1577 }
1578
1579 /* If the encoding is set but not the error handler,
1580 use "strict" error handler by default.
1581 PYTHONIOENCODING=latin1 behaves as
1582 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001583 if (!errors) {
1584 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001585 }
1586 }
1587
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001588 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001589 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1590 errors,
1591 "PYTHONIOENCODING environment variable");
1592 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001593 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001594 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001595 }
1596 }
1597
1598 PyMem_RawFree(pythonioencoding);
1599 }
1600
1601 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001602 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001603 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001604 status = PyConfig_SetString(config, &config->stdio_encoding,
1605 L"utf-8");
1606 if (_PyStatus_EXCEPTION(status)) {
1607 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001608 }
1609 }
1610 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001611 status = PyConfig_SetString(config, &config->stdio_errors,
1612 L"surrogateescape");
1613 if (_PyStatus_EXCEPTION(status)) {
1614 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001615 }
1616 }
1617 }
1618
1619 /* Choose the default error handler based on the current locale. */
1620 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001621 status = config_get_locale_encoding(config, &config->stdio_encoding);
1622 if (_PyStatus_EXCEPTION(status)) {
1623 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001624 }
1625 }
1626 if (config->stdio_errors == NULL) {
Andy Lesteraa450a02020-03-07 11:36:04 -06001627 const wchar_t *errors = config_get_stdio_errors();
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001628 assert(errors != NULL);
1629
Victor Stinner331a6a52019-05-27 16:39:22 +02001630 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1631 if (_PyStatus_EXCEPTION(status)) {
1632 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001633 }
1634 }
1635
Victor Stinner331a6a52019-05-27 16:39:22 +02001636 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001637}
1638
1639
Victor Stinner331a6a52019-05-27 16:39:22 +02001640static PyStatus
1641config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001642{
Victor Stinner331a6a52019-05-27 16:39:22 +02001643 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001644
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001645 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001646#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001647 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001648#else
Victor Stinnere2510952019-05-02 11:28:57 -04001649
1650#ifdef MS_WINDOWS
1651 if (preconfig->legacy_windows_fs_encoding) {
1652 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001653 status = PyConfig_SetString(config, &config->filesystem_encoding,
1654 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001655 }
1656 else
1657#endif
Victor Stinner20004952019-03-26 02:31:11 +01001658 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001659 status = PyConfig_SetString(config, &config->filesystem_encoding,
1660 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001661 }
Victor Stinnere2510952019-05-02 11:28:57 -04001662#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001663 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001664 status = PyConfig_SetString(config, &config->filesystem_encoding,
1665 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001666 }
Victor Stinnere2510952019-05-02 11:28:57 -04001667#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001668 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001669#ifdef MS_WINDOWS
1670 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001671 status = PyConfig_SetString(config, &config->filesystem_encoding,
1672 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001673#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001674 status = config_get_locale_encoding(config,
1675 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001676#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001677 }
Victor Stinnere2510952019-05-02 11:28:57 -04001678#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001679
Victor Stinner331a6a52019-05-27 16:39:22 +02001680 if (_PyStatus_EXCEPTION(status)) {
1681 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001682 }
1683 }
1684
1685 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001686 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001687#ifdef MS_WINDOWS
1688 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001689 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001690 }
1691 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001692 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001693 }
1694#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001695 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001696#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001697 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1698 if (_PyStatus_EXCEPTION(status)) {
1699 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001700 }
1701 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001702 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001703}
1704
1705
Victor Stinner331a6a52019-05-27 16:39:22 +02001706static PyStatus
1707config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001708{
Victor Stinner331a6a52019-05-27 16:39:22 +02001709 PyStatus status;
1710 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001711
Victor Stinner20004952019-03-26 02:31:11 +01001712 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001713 status = config_read_env_vars(config);
1714 if (_PyStatus_EXCEPTION(status)) {
1715 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001716 }
1717 }
1718
1719 /* -X options */
1720 if (config_get_xoption(config, L"showrefcount")) {
1721 config->show_ref_count = 1;
1722 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001723
Victor Stinner331a6a52019-05-27 16:39:22 +02001724 status = config_read_complex_options(config);
1725 if (_PyStatus_EXCEPTION(status)) {
1726 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001727 }
1728
Victor Stinner6c785c02018-08-01 17:56:14 +02001729 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001730 status = config_init_home(config);
1731 if (_PyStatus_EXCEPTION(status)) {
1732 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001733 }
1734 }
1735
Steve Dower177a41a2018-11-17 20:41:48 -08001736 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001737 status = config_init_executable(config);
1738 if (_PyStatus_EXCEPTION(status)) {
1739 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001740 }
1741 }
1742
Sandro Mani8f023a22020-06-08 17:28:11 +02001743 if(config->platlibdir == NULL) {
1744 status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR,
1745 "PLATLIBDIR macro");
1746 if (_PyStatus_EXCEPTION(status)) {
1747 return status;
1748 }
1749 }
1750
Victor Stinner6c785c02018-08-01 17:56:14 +02001751 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001752 status = _PyConfig_InitPathConfig(config);
1753 if (_PyStatus_EXCEPTION(status)) {
1754 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001755 }
1756 }
1757
1758 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001759 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001760 if (config->faulthandler < 0) {
1761 config->faulthandler = 1;
1762 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001763 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001764 if (config->faulthandler < 0) {
1765 config->faulthandler = 0;
1766 }
1767 if (config->tracemalloc < 0) {
1768 config->tracemalloc = 0;
1769 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001770 if (config->use_hash_seed < 0) {
1771 config->use_hash_seed = 0;
1772 config->hash_seed = 0;
1773 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001774
Victor Stinner70fead22018-08-29 13:45:34 +02001775 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001776 status = config_init_fs_encoding(config, preconfig);
1777 if (_PyStatus_EXCEPTION(status)) {
1778 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001779 }
1780 }
1781
Victor Stinner331a6a52019-05-27 16:39:22 +02001782 status = config_init_stdio_encoding(config, preconfig);
1783 if (_PyStatus_EXCEPTION(status)) {
1784 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001785 }
1786
Victor Stinner62599762019-03-15 16:03:23 +01001787 if (config->argv.length < 1) {
1788 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001789 status = PyWideStringList_Append(&config->argv, L"");
1790 if (_PyStatus_EXCEPTION(status)) {
1791 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001792 }
1793 }
Victor Stinner870b0352019-05-17 03:15:12 +02001794
1795 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001796 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1797 L"default");
1798 if (_PyStatus_EXCEPTION(status)) {
1799 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001800 }
1801 }
1802
1803 if (config->configure_c_stdio < 0) {
1804 config->configure_c_stdio = 1;
1805 }
1806
Victor Stinner331a6a52019-05-27 16:39:22 +02001807 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001808}
Victor Stinner5ed69952018-11-06 15:59:52 +01001809
1810
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001811static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001812config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001813{
1814#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1815 /* don't translate newlines (\r\n <=> \n) */
1816 _setmode(fileno(stdin), O_BINARY);
1817 _setmode(fileno(stdout), O_BINARY);
1818 _setmode(fileno(stderr), O_BINARY);
1819#endif
1820
1821 if (!config->buffered_stdio) {
1822#ifdef HAVE_SETVBUF
1823 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1824 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1825 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1826#else /* !HAVE_SETVBUF */
1827 setbuf(stdin, (char *)NULL);
1828 setbuf(stdout, (char *)NULL);
1829 setbuf(stderr, (char *)NULL);
1830#endif /* !HAVE_SETVBUF */
1831 }
1832 else if (config->interactive) {
1833#ifdef MS_WINDOWS
1834 /* Doesn't have to have line-buffered -- use unbuffered */
1835 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1836 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1837#else /* !MS_WINDOWS */
1838#ifdef HAVE_SETVBUF
1839 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1840 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1841#endif /* HAVE_SETVBUF */
1842#endif /* !MS_WINDOWS */
1843 /* Leave stderr alone - it should be unbuffered anyway. */
1844 }
1845}
1846
1847
1848/* Write the configuration:
1849
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001850 - set Py_xxx global configuration variables
1851 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinnere81f6e62020-06-08 18:12:59 +02001852PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +02001853_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001854{
Victor Stinner331a6a52019-05-27 16:39:22 +02001855 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001856
1857 if (config->configure_c_stdio) {
1858 config_init_stdio(config);
1859 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001860
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001861 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001862 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001863 preconfig->isolated = config->isolated;
1864 preconfig->use_environment = config->use_environment;
1865 preconfig->dev_mode = config->dev_mode;
Victor Stinnere81f6e62020-06-08 18:12:59 +02001866
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02001867 if (_Py_SetArgcArgv(config->orig_argv.length,
1868 config->orig_argv.items) < 0)
Victor Stinnere81f6e62020-06-08 18:12:59 +02001869 {
1870 return _PyStatus_NO_MEMORY();
1871 }
1872 return _PyStatus_OK();
Victor Stinner5ed69952018-11-06 15:59:52 +01001873}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001874
1875
Victor Stinner331a6a52019-05-27 16:39:22 +02001876/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001877
1878static void
Victor Stinner2f549082019-03-29 15:13:46 +01001879config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001880{
Victor Stinner2f549082019-03-29 15:13:46 +01001881 FILE *f = error ? stderr : stdout;
1882
1883 fprintf(f, usage_line, program);
1884 if (error)
1885 fprintf(f, "Try `python -h' for more information.\n");
1886 else {
1887 fputs(usage_1, f);
1888 fputs(usage_2, f);
1889 fputs(usage_3, f);
1890 fprintf(f, usage_4, (wint_t)DELIM);
1891 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1892 fputs(usage_6, f);
1893 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001894}
1895
1896
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001897/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001898static PyStatus
1899config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001900 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001901{
Victor Stinner331a6a52019-05-27 16:39:22 +02001902 PyStatus status;
1903 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001904 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001905 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001906
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001907 _PyOS_ResetGetOpt();
1908 do {
1909 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001910 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001911 if (c == EOF) {
1912 break;
1913 }
1914
1915 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001916 if (config->run_command == NULL) {
1917 /* -c is the last option; following arguments
1918 that look like options are left for the
1919 command to interpret. */
1920 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1921 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1922 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001923 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001924 }
1925 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1926 command[len - 2] = '\n';
1927 command[len - 1] = 0;
1928 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001929 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001930 break;
1931 }
1932
1933 if (c == 'm') {
1934 /* -m is the last option; following arguments
1935 that look like options are left for the
1936 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001937 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001938 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1939 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001940 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001941 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001942 }
1943 break;
1944 }
1945
1946 switch (c) {
1947 case 0:
1948 // Handle long option.
1949 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001950 if (wcscmp(_PyOS_optarg, L"always") == 0
1951 || wcscmp(_PyOS_optarg, L"never") == 0
1952 || wcscmp(_PyOS_optarg, L"default") == 0)
1953 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001954 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1955 _PyOS_optarg);
1956 if (_PyStatus_EXCEPTION(status)) {
1957 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001958 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001959 } else {
1960 fprintf(stderr, "--check-hash-based-pycs must be one of "
1961 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001962 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001963 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001964 }
1965 break;
1966
1967 case 'b':
1968 config->bytes_warning++;
1969 break;
1970
1971 case 'd':
1972 config->parser_debug++;
1973 break;
1974
1975 case 'i':
1976 config->inspect++;
1977 config->interactive++;
1978 break;
1979
Victor Stinner6dcb5422019-03-05 02:44:12 +01001980 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001981 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001982 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001983 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001984 break;
1985
1986 /* case 'J': reserved for Jython */
1987
1988 case 'O':
1989 config->optimization_level++;
1990 break;
1991
1992 case 'B':
1993 config->write_bytecode = 0;
1994 break;
1995
1996 case 's':
1997 config->user_site_directory = 0;
1998 break;
1999
2000 case 'S':
2001 config->site_import = 0;
2002 break;
2003
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002004 case 't':
2005 /* ignored for backwards compatibility */
2006 break;
2007
2008 case 'u':
2009 config->buffered_stdio = 0;
2010 break;
2011
2012 case 'v':
2013 config->verbose++;
2014 break;
2015
2016 case 'x':
2017 config->skip_source_first_line = 1;
2018 break;
2019
2020 case 'h':
2021 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02002022 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002023 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002024
2025 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01002026 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002027 break;
2028
2029 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002030 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2031 if (_PyStatus_EXCEPTION(status)) {
2032 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002033 }
2034 break;
2035
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002036 case 'q':
2037 config->quiet++;
2038 break;
2039
2040 case 'R':
2041 config->use_hash_seed = 0;
2042 break;
2043
2044 /* This space reserved for other options */
2045
2046 default:
2047 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002048 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002049 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002050 }
2051 } while (1);
2052
Victor Stinner2f549082019-03-29 15:13:46 +01002053 if (print_version) {
2054 printf("Python %s\n",
2055 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002056 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002057 }
2058
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002059 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002060 && _PyOS_optind < argv->length
2061 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002062 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002063 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002064 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002065 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002066 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002067 }
2068 }
2069
2070 if (config->run_command != NULL || config->run_module != NULL) {
2071 /* Backup _PyOS_optind */
2072 _PyOS_optind--;
2073 }
2074
Victor Stinnerae239f62019-05-16 17:02:56 +02002075 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002076
Victor Stinner331a6a52019-05-27 16:39:22 +02002077 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002078}
2079
2080
2081#ifdef MS_WINDOWS
2082# define WCSTOK wcstok_s
2083#else
2084# define WCSTOK wcstok
2085#endif
2086
2087/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002088static PyStatus
2089config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002090{
Victor Stinner331a6a52019-05-27 16:39:22 +02002091 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002092 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2093 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002094 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002095 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002096 if (_PyStatus_EXCEPTION(status)) {
2097 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002098 }
2099
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002100 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002101 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002102 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002103 }
2104
2105
2106 wchar_t *warning, *context = NULL;
2107 for (warning = WCSTOK(env, L",", &context);
2108 warning != NULL;
2109 warning = WCSTOK(NULL, L",", &context))
2110 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002111 status = PyWideStringList_Append(warnoptions, warning);
2112 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002113 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002114 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002115 }
2116 }
2117 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002118 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002119}
2120
2121
Victor Stinner331a6a52019-05-27 16:39:22 +02002122static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002123warnoptions_append(PyConfig *config, PyWideStringList *options,
2124 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002125{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002126 /* config_init_warnoptions() add existing config warnoptions at the end:
2127 ensure that the new option is not already present in this list to
2128 prevent change the options order whne config_init_warnoptions() is
2129 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002130 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002131 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002132 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002133 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002134 if (_PyWideStringList_Find(options, option)) {
2135 /* Already present: do nothing */
2136 return _PyStatus_OK();
2137 }
2138 return PyWideStringList_Append(options, option);
2139}
2140
2141
2142static PyStatus
2143warnoptions_extend(PyConfig *config, PyWideStringList *options,
2144 const PyWideStringList *options2)
2145{
2146 const Py_ssize_t len = options2->length;
2147 wchar_t *const *items = options2->items;
2148
2149 for (Py_ssize_t i = 0; i < len; i++) {
2150 PyStatus status = warnoptions_append(config, options, items[i]);
2151 if (_PyStatus_EXCEPTION(status)) {
2152 return status;
2153 }
2154 }
2155 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002156}
2157
2158
Victor Stinner331a6a52019-05-27 16:39:22 +02002159static PyStatus
2160config_init_warnoptions(PyConfig *config,
2161 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002162 const PyWideStringList *env_warnoptions,
2163 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002164{
Victor Stinner331a6a52019-05-27 16:39:22 +02002165 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002166 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002167
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002168 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002169 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002170 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002171 * - PyConfig.dev_mode: "default" filter
2172 * - PYTHONWARNINGS environment variable
2173 * - '-W' command line options
2174 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2175 * "default::BytesWarning" or "error::BytesWarning" filter
2176 * - early PySys_AddWarnOption() calls
2177 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002178 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002179 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2180 * module works on the basis of "the most recently added filter will be
2181 * checked first", we add the lowest precedence entries first so that later
2182 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002183 */
2184
Victor Stinner20004952019-03-26 02:31:11 +01002185 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002186 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002187 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002188 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002189 }
2190 }
2191
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002192 status = warnoptions_extend(config, &options, env_warnoptions);
2193 if (_PyStatus_EXCEPTION(status)) {
2194 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002195 }
2196
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002197 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2198 if (_PyStatus_EXCEPTION(status)) {
2199 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002200 }
2201
2202 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2203 * don't even try to emit a warning, so we skip setting the filter in that
2204 * case.
2205 */
2206 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002207 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002208 if (config->bytes_warning> 1) {
2209 filter = L"error::BytesWarning";
2210 }
2211 else {
2212 filter = L"default::BytesWarning";
2213 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002214 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002215 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002216 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002217 }
2218 }
Victor Stinner120b7072019-08-23 18:03:08 +01002219
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002220 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002221 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002222 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002223 }
2224
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002225 /* Always add all PyConfig.warnoptions options */
2226 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2227 if (_PyStatus_EXCEPTION(status)) {
2228 goto error;
2229 }
2230
2231 _PyWideStringList_Clear(&config->warnoptions);
2232 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002233 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002234
2235error:
2236 _PyWideStringList_Clear(&options);
2237 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002238}
2239
2240
Victor Stinner331a6a52019-05-27 16:39:22 +02002241static PyStatus
2242config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002243{
Victor Stinner331a6a52019-05-27 16:39:22 +02002244 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002245 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002246
Victor Stinner74f65682019-03-15 15:08:05 +01002247 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002248 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002249 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002250 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2251 if (_PyStatus_EXCEPTION(status)) {
2252 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002253 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002254 }
2255 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002256 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002257 slice.length = cmdline_argv->length - opt_index;
2258 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002259 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2260 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002261 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002262 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002263 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002264
2265 wchar_t *arg0 = NULL;
2266 if (config->run_command != NULL) {
2267 /* Force sys.argv[0] = '-c' */
2268 arg0 = L"-c";
2269 }
2270 else if (config->run_module != NULL) {
2271 /* Force sys.argv[0] = '-m'*/
2272 arg0 = L"-m";
2273 }
Victor Stinner3939c322019-06-25 15:02:43 +02002274
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002275 if (arg0 != NULL) {
2276 arg0 = _PyMem_RawWcsdup(arg0);
2277 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002278 _PyWideStringList_Clear(&config_argv);
2279 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002280 }
2281
Victor Stinnerfa153762019-03-20 04:25:38 +01002282 PyMem_RawFree(config_argv.items[0]);
2283 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002284 }
2285
Victor Stinner331a6a52019-05-27 16:39:22 +02002286 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002287 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002288 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002289}
2290
2291
Victor Stinner331a6a52019-05-27 16:39:22 +02002292static PyStatus
2293core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002294{
Victor Stinner331a6a52019-05-27 16:39:22 +02002295 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002296
Victor Stinnercab5d072019-05-17 19:01:14 +02002297 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002298 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2299 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002300 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002301 }
2302
Victor Stinner331a6a52019-05-27 16:39:22 +02002303 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002304
2305 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2306 if (_PyStatus_EXCEPTION(status)) {
2307 return status;
2308 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002309
Victor Stinner331a6a52019-05-27 16:39:22 +02002310 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002311
Victor Stinner331a6a52019-05-27 16:39:22 +02002312 status = _PyPreCmdline_Read(precmdline, &preconfig);
2313 if (_PyStatus_EXCEPTION(status)) {
2314 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002315 }
2316
Victor Stinner331a6a52019-05-27 16:39:22 +02002317 status = _PyPreCmdline_SetConfig(precmdline, config);
2318 if (_PyStatus_EXCEPTION(status)) {
2319 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002320 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002321 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002322}
2323
2324
Victor Stinner3939c322019-06-25 15:02:43 +02002325/* Get run_filename absolute path */
2326static PyStatus
2327config_run_filename_abspath(PyConfig *config)
2328{
2329 if (!config->run_filename) {
2330 return _PyStatus_OK();
2331 }
2332
2333#ifndef MS_WINDOWS
2334 if (_Py_isabs(config->run_filename)) {
2335 /* path is already absolute */
2336 return _PyStatus_OK();
2337 }
2338#endif
2339
2340 wchar_t *abs_filename;
2341 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2342 /* failed to get the absolute path of the command line filename:
2343 ignore the error, keep the relative path */
2344 return _PyStatus_OK();
2345 }
2346 if (abs_filename == NULL) {
2347 return _PyStatus_NO_MEMORY();
2348 }
2349
2350 PyMem_RawFree(config->run_filename);
2351 config->run_filename = abs_filename;
2352 return _PyStatus_OK();
2353}
2354
2355
Victor Stinner331a6a52019-05-27 16:39:22 +02002356static PyStatus
2357config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002358{
Victor Stinner331a6a52019-05-27 16:39:22 +02002359 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002360 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2361 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2362 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002363
Victor Stinnerae239f62019-05-16 17:02:56 +02002364 if (config->parse_argv < 0) {
2365 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002366 }
Victor Stinner870b0352019-05-17 03:15:12 +02002367
Victor Stinnerfed02e12019-05-17 11:12:09 +02002368 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002369 status = config_init_program_name(config);
2370 if (_PyStatus_EXCEPTION(status)) {
2371 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002372 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002373 }
Victor Stinner2f549082019-03-29 15:13:46 +01002374
Victor Stinnerae239f62019-05-16 17:02:56 +02002375 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002376 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002377 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2378 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002379 goto done;
2380 }
2381
Victor Stinner3939c322019-06-25 15:02:43 +02002382 status = config_run_filename_abspath(config);
2383 if (_PyStatus_EXCEPTION(status)) {
2384 goto done;
2385 }
2386
Victor Stinner331a6a52019-05-27 16:39:22 +02002387 status = config_update_argv(config, opt_index);
2388 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002389 goto done;
2390 }
Victor Stinner2f549082019-03-29 15:13:46 +01002391 }
Victor Stinner3939c322019-06-25 15:02:43 +02002392 else {
2393 status = config_run_filename_abspath(config);
2394 if (_PyStatus_EXCEPTION(status)) {
2395 goto done;
2396 }
2397 }
Victor Stinner2f549082019-03-29 15:13:46 +01002398
Victor Stinner2f549082019-03-29 15:13:46 +01002399 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002400 status = config_init_env_warnoptions(config, &env_warnoptions);
2401 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002402 goto done;
2403 }
2404 }
2405
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002406 /* Handle early PySys_AddWarnOption() calls */
2407 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2408 if (_PyStatus_EXCEPTION(status)) {
2409 goto done;
2410 }
2411
Victor Stinner331a6a52019-05-27 16:39:22 +02002412 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002413 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002414 &env_warnoptions,
2415 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002416 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002417 goto done;
2418 }
2419
Victor Stinner331a6a52019-05-27 16:39:22 +02002420 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002421
2422done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002423 _PyWideStringList_Clear(&cmdline_warnoptions);
2424 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002425 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002426 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002427}
2428
2429
Victor Stinner331a6a52019-05-27 16:39:22 +02002430PyStatus
2431_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002432{
Victor Stinner331a6a52019-05-27 16:39:22 +02002433 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2434 if (_PyStatus_EXCEPTION(status)) {
2435 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002436 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002437
Victor Stinner5f38b842019-05-01 02:30:12 +02002438 return _PyArgv_AsWstrList(args, &config->argv);
2439}
2440
2441
Victor Stinner70005ac2019-05-02 15:25:34 -04002442/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2443 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002444PyStatus
2445PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002446{
2447 _PyArgv args = {
2448 .argc = argc,
2449 .use_bytes_argv = 1,
2450 .bytes_argv = argv,
2451 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002452 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002453}
2454
2455
Victor Stinner331a6a52019-05-27 16:39:22 +02002456PyStatus
2457PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002458{
2459 _PyArgv args = {
2460 .argc = argc,
2461 .use_bytes_argv = 0,
2462 .bytes_argv = NULL,
2463 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002464 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002465}
2466
2467
Victor Stinner36242fd2019-07-01 19:13:50 +02002468PyStatus
2469PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2470 Py_ssize_t length, wchar_t **items)
2471{
2472 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2473 if (_PyStatus_EXCEPTION(status)) {
2474 return status;
2475 }
2476
2477 PyWideStringList list2 = {.length = length, .items = items};
2478 if (_PyWideStringList_Copy(list, &list2) < 0) {
2479 return _PyStatus_NO_MEMORY();
2480 }
2481 return _PyStatus_OK();
2482}
2483
2484
Victor Stinner331a6a52019-05-27 16:39:22 +02002485/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002486
2487 * Command line arguments
2488 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002489 * Py_xxx global configuration variables
2490
2491 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002492PyStatus
2493PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002494{
Victor Stinner331a6a52019-05-27 16:39:22 +02002495 PyStatus status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002496
Victor Stinner331a6a52019-05-27 16:39:22 +02002497 status = _Py_PreInitializeFromConfig(config, NULL);
2498 if (_PyStatus_EXCEPTION(status)) {
2499 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002500 }
2501
Victor Stinner331a6a52019-05-27 16:39:22 +02002502 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002503
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002504 if (config->orig_argv.length == 0
Victor Stinnere81f6e62020-06-08 18:12:59 +02002505 && !(config->argv.length == 1
2506 && wcscmp(config->argv.items[0], L"") == 0))
2507 {
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002508 if (_PyWideStringList_Copy(&config->orig_argv, &config->argv) < 0) {
Victor Stinnere81f6e62020-06-08 18:12:59 +02002509 return _PyStatus_NO_MEMORY();
2510 }
Victor Stinnercab5d072019-05-17 19:01:14 +02002511 }
2512
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002513 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002514 status = core_read_precmdline(config, &precmdline);
2515 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002516 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002517 }
2518
Victor Stinner870b0352019-05-17 03:15:12 +02002519 assert(config->isolated >= 0);
2520 if (config->isolated) {
2521 config->use_environment = 0;
2522 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002523 }
2524
Victor Stinner331a6a52019-05-27 16:39:22 +02002525 status = config_read_cmdline(config);
2526 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002527 goto done;
2528 }
2529
Victor Stinner120b7072019-08-23 18:03:08 +01002530 /* Handle early PySys_AddXOption() calls */
2531 status = _PySys_ReadPreinitXOptions(config);
2532 if (_PyStatus_EXCEPTION(status)) {
2533 goto done;
2534 }
2535
Victor Stinner331a6a52019-05-27 16:39:22 +02002536 status = config_read(config);
2537 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002538 goto done;
2539 }
2540
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002541 /* Check config consistency */
2542 assert(config->isolated >= 0);
2543 assert(config->use_environment >= 0);
2544 assert(config->dev_mode >= 0);
2545 assert(config->install_signal_handlers >= 0);
2546 assert(config->use_hash_seed >= 0);
2547 assert(config->faulthandler >= 0);
2548 assert(config->tracemalloc >= 0);
2549 assert(config->site_import >= 0);
2550 assert(config->bytes_warning >= 0);
2551 assert(config->inspect >= 0);
2552 assert(config->interactive >= 0);
2553 assert(config->optimization_level >= 0);
2554 assert(config->parser_debug >= 0);
2555 assert(config->write_bytecode >= 0);
2556 assert(config->verbose >= 0);
2557 assert(config->quiet >= 0);
2558 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002559 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002560 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002561 assert(config->buffered_stdio >= 0);
2562 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002563 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002564 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2565 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002566 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2567 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2568 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002569 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002570 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002571 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002572 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002573 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002574 assert(config->prefix != NULL);
2575 assert(config->base_prefix != NULL);
2576 assert(config->exec_prefix != NULL);
2577 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002578 }
Sandro Mani8f023a22020-06-08 17:28:11 +02002579 assert(config->platlibdir != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002580 assert(config->filesystem_encoding != NULL);
2581 assert(config->filesystem_errors != NULL);
2582 assert(config->stdio_encoding != NULL);
2583 assert(config->stdio_errors != NULL);
2584#ifdef MS_WINDOWS
2585 assert(config->legacy_windows_stdio >= 0);
2586#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002587 /* -c and -m options are exclusive */
2588 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002589 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002590 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002591 assert(config->pathconfig_warnings >= 0);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002592 assert(_PyWideStringList_CheckConsistency(&config->orig_argv));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002593
Victor Stinner331a6a52019-05-27 16:39:22 +02002594 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002595
2596done:
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002597 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002598 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002599}
Victor Stinner1075d162019-03-25 23:19:57 +01002600
2601
2602PyObject*
2603_Py_GetConfigsAsDict(void)
2604{
Victor Stinner331a6a52019-05-27 16:39:22 +02002605 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002606 PyObject *dict = NULL;
2607
Victor Stinner331a6a52019-05-27 16:39:22 +02002608 result = PyDict_New();
2609 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002610 goto error;
2611 }
2612
Victor Stinner331a6a52019-05-27 16:39:22 +02002613 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002614 dict = _Py_GetGlobalVariablesAsDict();
2615 if (dict == NULL) {
2616 goto error;
2617 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002618 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002619 goto error;
2620 }
2621 Py_CLEAR(dict);
2622
2623 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002624 PyThreadState *tstate = _PyThreadState_GET();
2625 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002626 dict = _PyPreConfig_AsDict(pre_config);
2627 if (dict == NULL) {
2628 goto error;
2629 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002630 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002631 goto error;
2632 }
2633 Py_CLEAR(dict);
2634
2635 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002636 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinner331a6a52019-05-27 16:39:22 +02002637 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002638 if (dict == NULL) {
2639 goto error;
2640 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002641 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002642 goto error;
2643 }
2644 Py_CLEAR(dict);
2645
Victor Stinner331a6a52019-05-27 16:39:22 +02002646 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002647
2648error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002649 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002650 Py_XDECREF(dict);
2651 return NULL;
2652}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002653
2654
2655static void
2656init_dump_ascii_wstr(const wchar_t *str)
2657{
2658 if (str == NULL) {
2659 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002660 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002661 }
2662
2663 PySys_WriteStderr("'");
2664 for (; *str != L'\0'; str++) {
2665 wchar_t ch = *str;
2666 if (ch == L'\'') {
2667 PySys_WriteStderr("\\'");
2668 } else if (0x20 <= ch && ch < 0x7f) {
2669 PySys_WriteStderr("%lc", ch);
2670 }
2671 else if (ch <= 0xff) {
2672 PySys_WriteStderr("\\x%02x", ch);
2673 }
2674#if SIZEOF_WCHAR_T > 2
2675 else if (ch > 0xffff) {
2676 PySys_WriteStderr("\\U%08x", ch);
2677 }
2678#endif
2679 else {
2680 PySys_WriteStderr("\\u%04x", ch);
2681 }
2682 }
2683 PySys_WriteStderr("'");
2684}
2685
2686
2687/* Dump the Python path configuration into sys.stderr */
2688void
2689_Py_DumpPathConfig(PyThreadState *tstate)
2690{
2691 PyObject *exc_type, *exc_value, *exc_tb;
2692 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2693
2694 PySys_WriteStderr("Python path configuration:\n");
2695
2696#define DUMP_CONFIG(NAME, FIELD) \
2697 do { \
2698 PySys_WriteStderr(" " NAME " = "); \
2699 init_dump_ascii_wstr(config->FIELD); \
2700 PySys_WriteStderr("\n"); \
2701 } while (0)
2702
Victor Stinnerda7933e2020-04-13 03:04:28 +02002703 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002704 DUMP_CONFIG("PYTHONHOME", home);
2705 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2706 DUMP_CONFIG("program name", program_name);
2707 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2708 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2709 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2710 PySys_WriteStderr(" import site = %i\n", config->site_import);
2711#undef DUMP_CONFIG
2712
2713#define DUMP_SYS(NAME) \
2714 do { \
2715 obj = PySys_GetObject(#NAME); \
2716 PySys_FormatStderr(" sys.%s = ", #NAME); \
2717 if (obj != NULL) { \
2718 PySys_FormatStderr("%A", obj); \
2719 } \
2720 else { \
2721 PySys_WriteStderr("(not set)"); \
2722 } \
2723 PySys_FormatStderr("\n"); \
2724 } while (0)
2725
2726 PyObject *obj;
2727 DUMP_SYS(_base_executable);
2728 DUMP_SYS(base_prefix);
2729 DUMP_SYS(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +02002730 DUMP_SYS(platlibdir);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002731 DUMP_SYS(executable);
2732 DUMP_SYS(prefix);
2733 DUMP_SYS(exec_prefix);
2734#undef DUMP_SYS
2735
2736 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2737 if (sys_path != NULL && PyList_Check(sys_path)) {
2738 PySys_WriteStderr(" sys.path = [\n");
2739 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2740 for (Py_ssize_t i=0; i < len; i++) {
2741 PyObject *path = PyList_GET_ITEM(sys_path, i);
2742 PySys_FormatStderr(" %A,\n", path);
2743 }
2744 PySys_WriteStderr(" ]\n");
2745 }
2746
2747 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2748}