blob: 880e145ec031cd10ac2b2a03a44fb7ef765db21b [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\
Serhiy Storchaka58de1dd2020-09-09 03:28:02 +030086 -X dev: enable CPython's \"development mode\", introducing additional runtime\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000087 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{
Victor Stinner8f427482020-07-08 00:20:37 +0200871 PyObject *dict = PyDict_New();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100872 if (dict == NULL) {
873 return NULL;
874 }
875
876#define SET_ITEM(KEY, EXPR) \
877 do { \
878 PyObject *obj = (EXPR); \
879 if (obj == NULL) { \
880 goto fail; \
881 } \
882 int res = PyDict_SetItemString(dict, (KEY), obj); \
883 Py_DECREF(obj); \
884 if (res < 0) { \
885 goto fail; \
886 } \
887 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100888#define SET_ITEM_INT(ATTR) \
889 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
890#define SET_ITEM_UINT(ATTR) \
891 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100892#define FROM_WSTRING(STR) \
893 ((STR != NULL) ? \
894 PyUnicode_FromWideChar(STR, -1) \
895 : (Py_INCREF(Py_None), Py_None))
896#define SET_ITEM_WSTR(ATTR) \
897 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
898#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200899 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100900
Victor Stinner6d1c4672019-05-20 11:02:00 +0200901 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100902 SET_ITEM_INT(isolated);
903 SET_ITEM_INT(use_environment);
904 SET_ITEM_INT(dev_mode);
905 SET_ITEM_INT(install_signal_handlers);
906 SET_ITEM_INT(use_hash_seed);
907 SET_ITEM_UINT(hash_seed);
908 SET_ITEM_INT(faulthandler);
909 SET_ITEM_INT(tracemalloc);
910 SET_ITEM_INT(import_time);
911 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100912 SET_ITEM_INT(dump_refs);
913 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400914 SET_ITEM_WSTR(filesystem_encoding);
915 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100916 SET_ITEM_WSTR(pycache_prefix);
917 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200918 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100919 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100920 SET_ITEM_WSTRLIST(xoptions);
921 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200922 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100923 SET_ITEM_WSTR(home);
924 SET_ITEM_WSTRLIST(module_search_paths);
925 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700926 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100927 SET_ITEM_WSTR(prefix);
928 SET_ITEM_WSTR(base_prefix);
929 SET_ITEM_WSTR(exec_prefix);
930 SET_ITEM_WSTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200931 SET_ITEM_WSTR(platlibdir);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100932 SET_ITEM_INT(site_import);
933 SET_ITEM_INT(bytes_warning);
934 SET_ITEM_INT(inspect);
935 SET_ITEM_INT(interactive);
936 SET_ITEM_INT(optimization_level);
937 SET_ITEM_INT(parser_debug);
938 SET_ITEM_INT(write_bytecode);
939 SET_ITEM_INT(verbose);
940 SET_ITEM_INT(quiet);
941 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200942 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100943 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400944 SET_ITEM_WSTR(stdio_encoding);
945 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100946#ifdef MS_WINDOWS
947 SET_ITEM_INT(legacy_windows_stdio);
948#endif
949 SET_ITEM_INT(skip_source_first_line);
950 SET_ITEM_WSTR(run_command);
951 SET_ITEM_WSTR(run_module);
952 SET_ITEM_WSTR(run_filename);
953 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400954 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200955 SET_ITEM_INT(pathconfig_warnings);
956 SET_ITEM_INT(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200957 SET_ITEM_INT(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200958 SET_ITEM_WSTRLIST(orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100959
960 return dict;
961
962fail:
963 Py_DECREF(dict);
964 return NULL;
965
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100966#undef FROM_WSTRING
967#undef SET_ITEM
968#undef SET_ITEM_INT
969#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100970#undef SET_ITEM_WSTR
971#undef SET_ITEM_WSTRLIST
972}
973
974
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100975static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200976config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200977{
Victor Stinner20004952019-03-26 02:31:11 +0100978 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200979}
980
981
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100982/* Get a copy of the environment variable as wchar_t*.
983 Return 0 on success, but *dest can be NULL.
984 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200985static PyStatus
986config_get_env_dup(PyConfig *config,
987 wchar_t **dest,
988 wchar_t *wname, char *name,
989 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200990{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200991 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100992 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200993
Victor Stinner20004952019-03-26 02:31:11 +0100994 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200995 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200996 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200997 }
998
999#ifdef MS_WINDOWS
1000 const wchar_t *var = _wgetenv(wname);
1001 if (!var || var[0] == '\0') {
1002 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001003 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001004 }
1005
Victor Stinner331a6a52019-05-27 16:39:22 +02001006 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +02001007#else
1008 const char *var = getenv(name);
1009 if (!var || var[0] == '\0') {
1010 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001011 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001012 }
1013
Victor Stinner331a6a52019-05-27 16:39:22 +02001014 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001015#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001016}
1017
1018
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001019#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001020 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001021
1022
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001023static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001024config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001025{
Victor Stinner022be022019-05-22 23:58:50 +02001026 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1027 /* Python and Isolated configuration ignore global variables */
1028 return;
1029 }
1030
Victor Stinner6c785c02018-08-01 17:56:14 +02001031#define COPY_FLAG(ATTR, VALUE) \
1032 if (config->ATTR == -1) { \
1033 config->ATTR = VALUE; \
1034 }
1035#define COPY_NOT_FLAG(ATTR, VALUE) \
1036 if (config->ATTR == -1) { \
1037 config->ATTR = !(VALUE); \
1038 }
1039
Victor Stinner20004952019-03-26 02:31:11 +01001040 COPY_FLAG(isolated, Py_IsolatedFlag);
1041 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001042 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1043 COPY_FLAG(inspect, Py_InspectFlag);
1044 COPY_FLAG(interactive, Py_InteractiveFlag);
1045 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1046 COPY_FLAG(parser_debug, Py_DebugFlag);
1047 COPY_FLAG(verbose, Py_VerboseFlag);
1048 COPY_FLAG(quiet, Py_QuietFlag);
1049#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001050 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1051#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001052 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001053
Victor Stinner6c785c02018-08-01 17:56:14 +02001054 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1055 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1056 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1057 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1058
Victor Stinner6c785c02018-08-01 17:56:14 +02001059#undef COPY_FLAG
1060#undef COPY_NOT_FLAG
1061}
1062
1063
1064/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001065static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001066config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001067{
1068#define COPY_FLAG(ATTR, VAR) \
1069 if (config->ATTR != -1) { \
1070 VAR = config->ATTR; \
1071 }
1072#define COPY_NOT_FLAG(ATTR, VAR) \
1073 if (config->ATTR != -1) { \
1074 VAR = !config->ATTR; \
1075 }
1076
Victor Stinner20004952019-03-26 02:31:11 +01001077 COPY_FLAG(isolated, Py_IsolatedFlag);
1078 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001079 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1080 COPY_FLAG(inspect, Py_InspectFlag);
1081 COPY_FLAG(interactive, Py_InteractiveFlag);
1082 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1083 COPY_FLAG(parser_debug, Py_DebugFlag);
1084 COPY_FLAG(verbose, Py_VerboseFlag);
1085 COPY_FLAG(quiet, Py_QuietFlag);
1086#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001087 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1088#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001089 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001090
Victor Stinner6c785c02018-08-01 17:56:14 +02001091 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1092 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1093 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1094 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1095
Victor Stinner6c785c02018-08-01 17:56:14 +02001096 /* Random or non-zero hash seed */
1097 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1098 config->hash_seed != 0);
1099
1100#undef COPY_FLAG
1101#undef COPY_NOT_FLAG
1102}
1103
1104
1105/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1106 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001107static PyStatus
1108config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001109{
Victor Stinner331a6a52019-05-27 16:39:22 +02001110 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001111
Victor Stinner6c785c02018-08-01 17:56:14 +02001112 /* If Py_SetProgramName() was called, use its value */
1113 const wchar_t *program_name = _Py_path_config.program_name;
1114 if (program_name != NULL) {
1115 config->program_name = _PyMem_RawWcsdup(program_name);
1116 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001117 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001118 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001119 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001120 }
1121
1122#ifdef __APPLE__
1123 /* On MacOS X, when the Python interpreter is embedded in an
1124 application bundle, it gets executed by a bootstrapping script
1125 that does os.execve() with an argv[0] that's different from the
1126 actual Python executable. This is needed to keep the Finder happy,
1127 or rather, to work around Apple's overly strict requirements of
1128 the process name. However, we still need a usable sys.executable,
1129 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001130 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001131 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001132 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001133 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001134 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1135 "PYTHONEXECUTABLE environment variable");
1136 if (_PyStatus_EXCEPTION(status)) {
1137 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001138 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001139 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001140 }
1141#ifdef WITH_NEXT_FRAMEWORK
1142 else {
1143 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1144 if (pyvenv_launcher && *pyvenv_launcher) {
1145 /* Used by Mac/Tools/pythonw.c to forward
1146 * the argv0 of the stub executable
1147 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001148 status = CONFIG_SET_BYTES_STR(config,
1149 &config->program_name,
1150 pyvenv_launcher,
1151 "__PYVENV_LAUNCHER__ environment variable");
1152 if (_PyStatus_EXCEPTION(status)) {
1153 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001154 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001155
1156 /*
1157 * This environment variable is used to communicate between
1158 * the stub launcher and the real interpreter and isn't needed
1159 * beyond this point.
1160 *
1161 * Clean up to avoid problems when launching other programs
1162 * later on.
1163 */
1164 (void)unsetenv("__PYVENV_LAUNCHER__");
1165
Victor Stinner331a6a52019-05-27 16:39:22 +02001166 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001167 }
1168 }
1169#endif /* WITH_NEXT_FRAMEWORK */
1170#endif /* __APPLE__ */
1171
Victor Stinnerfed02e12019-05-17 11:12:09 +02001172 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001173 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001174 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1175 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1176 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001177 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001178 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001179 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001180 }
1181
Victor Stinnerfed02e12019-05-17 11:12:09 +02001182 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001183#ifdef MS_WINDOWS
1184 const wchar_t *default_program_name = L"python";
1185#else
1186 const wchar_t *default_program_name = L"python3";
1187#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001188 status = PyConfig_SetString(config, &config->program_name,
1189 default_program_name);
1190 if (_PyStatus_EXCEPTION(status)) {
1191 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001192 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001193 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001194}
1195
Victor Stinner331a6a52019-05-27 16:39:22 +02001196static PyStatus
1197config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001198{
1199 assert(config->executable == NULL);
1200
1201 /* If Py_SetProgramFullPath() was called, use its value */
1202 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1203 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001204 PyStatus status = PyConfig_SetString(config,
1205 &config->executable,
1206 program_full_path);
1207 if (_PyStatus_EXCEPTION(status)) {
1208 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001209 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001210 return _PyStatus_OK();
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 Stinner6c785c02018-08-01 17:56:14 +02001214
Victor Stinner4fffd382019-03-06 01:44:31 +01001215
Victor Stinner6c785c02018-08-01 17:56:14 +02001216static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001217config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001218{
Victor Stinner74f65682019-03-15 15:08:05 +01001219 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001220}
1221
1222
Victor Stinner331a6a52019-05-27 16:39:22 +02001223static PyStatus
1224config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001225{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001226 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001227
1228 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001229 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001230 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001231 PyStatus status = PyConfig_SetString(config, &config->home, home);
1232 if (_PyStatus_EXCEPTION(status)) {
1233 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001234 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001235 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001236 }
1237
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001238 return CONFIG_GET_ENV_DUP(config, &config->home,
1239 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001240}
1241
1242
Victor Stinner331a6a52019-05-27 16:39:22 +02001243static PyStatus
1244config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001245{
Victor Stinner331a6a52019-05-27 16:39:22 +02001246 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001247
1248 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1249 /* Convert a text seed to a numeric one */
1250 if (seed_text && strcmp(seed_text, "random") != 0) {
1251 const char *endptr = seed_text;
1252 unsigned long seed;
1253 errno = 0;
1254 seed = strtoul(seed_text, (char **)&endptr, 10);
1255 if (*endptr != '\0'
1256 || seed > 4294967295UL
1257 || (errno == ERANGE && seed == ULONG_MAX))
1258 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001259 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001260 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001261 }
1262 /* Use a specific hash */
1263 config->use_hash_seed = 1;
1264 config->hash_seed = seed;
1265 }
1266 else {
1267 /* Use a random hash */
1268 config->use_hash_seed = 0;
1269 config->hash_seed = 0;
1270 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001271 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001272}
1273
1274
Victor Stinner6c785c02018-08-01 17:56:14 +02001275static int
1276config_wstr_to_int(const wchar_t *wstr, int *result)
1277{
1278 const wchar_t *endptr = wstr;
1279 errno = 0;
1280 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1281 if (*endptr != '\0' || errno == ERANGE) {
1282 return -1;
1283 }
1284 if (value < INT_MIN || value > INT_MAX) {
1285 return -1;
1286 }
1287
1288 *result = (int)value;
1289 return 0;
1290}
1291
1292
Victor Stinner331a6a52019-05-27 16:39:22 +02001293static PyStatus
1294config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001295{
Victor Stinner331a6a52019-05-27 16:39:22 +02001296 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001297 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001298
Victor Stinner6c785c02018-08-01 17:56:14 +02001299 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001300 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1301 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1302 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1303 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001304
1305 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001306 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001307 if (dont_write_bytecode) {
1308 config->write_bytecode = 0;
1309 }
1310
1311 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001312 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001313 if (no_user_site_directory) {
1314 config->user_site_directory = 0;
1315 }
1316
1317 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001318 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001319 if (unbuffered_stdio) {
1320 config->buffered_stdio = 0;
1321 }
1322
1323#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001324 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001325 "PYTHONLEGACYWINDOWSSTDIO");
1326#endif
1327
Victor Stinner331a6a52019-05-27 16:39:22 +02001328 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001329 config->dump_refs = 1;
1330 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001331 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001332 config->malloc_stats = 1;
1333 }
1334
Victor Stinner331a6a52019-05-27 16:39:22 +02001335 if (config->pythonpath_env == NULL) {
1336 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1337 L"PYTHONPATH", "PYTHONPATH");
1338 if (_PyStatus_EXCEPTION(status)) {
1339 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001340 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001341 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001342
Sandro Mani8f023a22020-06-08 17:28:11 +02001343 if(config->platlibdir == NULL) {
1344 status = CONFIG_GET_ENV_DUP(config, &config->platlibdir,
1345 L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR");
1346 if (_PyStatus_EXCEPTION(status)) {
1347 return status;
1348 }
1349 }
1350
Victor Stinner6c785c02018-08-01 17:56:14 +02001351 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001352 status = config_init_hash_seed(config);
1353 if (_PyStatus_EXCEPTION(status)) {
1354 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001355 }
1356 }
1357
Victor Stinner331a6a52019-05-27 16:39:22 +02001358 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001359}
1360
1361
Victor Stinner331a6a52019-05-27 16:39:22 +02001362static PyStatus
1363config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001364{
1365 int nframe;
1366 int valid;
1367
Victor Stinner331a6a52019-05-27 16:39:22 +02001368 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001369 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001370 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001371 valid = (nframe >= 0);
1372 }
1373 else {
1374 valid = 0;
1375 }
1376 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001377 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001378 }
1379 config->tracemalloc = nframe;
1380 }
1381
1382 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1383 if (xoption) {
1384 const wchar_t *sep = wcschr(xoption, L'=');
1385 if (sep) {
1386 if (!config_wstr_to_int(sep + 1, &nframe)) {
1387 valid = (nframe >= 0);
1388 }
1389 else {
1390 valid = 0;
1391 }
1392 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001393 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1394 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001395 }
1396 }
1397 else {
1398 /* -X tracemalloc behaves as -X tracemalloc=1 */
1399 nframe = 1;
1400 }
1401 config->tracemalloc = nframe;
1402 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001403 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001404}
1405
1406
Victor Stinner331a6a52019-05-27 16:39:22 +02001407static PyStatus
1408config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001409{
1410 assert(config->pycache_prefix == NULL);
1411
1412 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1413 if (xoption) {
1414 const wchar_t *sep = wcschr(xoption, L'=');
1415 if (sep && wcslen(sep) > 1) {
1416 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1417 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001418 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001419 }
1420 }
1421 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001422 // PYTHONPYCACHEPREFIX env var ignored
1423 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001424 config->pycache_prefix = NULL;
1425 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001426 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001427 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001428
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001429 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1430 L"PYTHONPYCACHEPREFIX",
1431 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001432}
1433
1434
Victor Stinner331a6a52019-05-27 16:39:22 +02001435static PyStatus
1436config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001437{
1438 /* More complex options configured by env var and -X option */
1439 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001440 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001441 || config_get_xoption(config, L"faulthandler")) {
1442 config->faulthandler = 1;
1443 }
1444 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001445 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001446 || config_get_xoption(config, L"importtime")) {
1447 config->import_time = 1;
1448 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001449
Victor Stinner331a6a52019-05-27 16:39:22 +02001450 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001451 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001452 status = config_init_tracemalloc(config);
1453 if (_PyStatus_EXCEPTION(status)) {
1454 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001455 }
1456 }
1457
1458 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001459 status = config_init_pycache_prefix(config);
1460 if (_PyStatus_EXCEPTION(status)) {
1461 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001462 }
1463 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001464 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001465}
1466
1467
Victor Stinner709d23d2019-05-02 14:56:30 -04001468static const wchar_t *
Andy Lesteraa450a02020-03-07 11:36:04 -06001469config_get_stdio_errors(void)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001470{
1471#ifndef MS_WINDOWS
1472 const char *loc = setlocale(LC_CTYPE, NULL);
1473 if (loc != NULL) {
1474 /* surrogateescape is the default in the legacy C and POSIX locales */
1475 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001476 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001477 }
1478
1479#ifdef PY_COERCE_C_LOCALE
1480 /* surrogateescape is the default in locale coercion target locales */
1481 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001482 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001483 }
1484#endif
1485 }
1486
Victor Stinner709d23d2019-05-02 14:56:30 -04001487 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001488#else
1489 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001490 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001491#endif
1492}
1493
1494
Victor Stinner331a6a52019-05-27 16:39:22 +02001495static PyStatus
1496config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001497{
1498#ifdef MS_WINDOWS
1499 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001500 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001501 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001502#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001503 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001504#else
1505 const char *encoding = nl_langinfo(CODESET);
1506 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001507 return _PyStatus_ERR("failed to get the locale encoding: "
1508 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001509 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001510 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001511 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001512 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001513 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001514#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001515}
1516
1517
Victor Stinner331a6a52019-05-27 16:39:22 +02001518static PyStatus
1519config_init_stdio_encoding(PyConfig *config,
1520 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001521{
Victor Stinner331a6a52019-05-27 16:39:22 +02001522 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001523
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001524 /* If Py_SetStandardStreamEncoding() have been called, use these
1525 parameters. */
1526 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001527 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1528 _Py_StandardStreamEncoding,
1529 "_Py_StandardStreamEncoding");
1530 if (_PyStatus_EXCEPTION(status)) {
1531 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001532 }
1533 }
1534
1535 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001536 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1537 _Py_StandardStreamErrors,
1538 "_Py_StandardStreamErrors");
1539 if (_PyStatus_EXCEPTION(status)) {
1540 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001541 }
1542 }
1543
1544 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001545 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001546 }
1547
1548 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001549 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001550 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001551 char *pythonioencoding = _PyMem_RawStrdup(opt);
1552 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001553 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001554 }
1555
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001556 char *errors = strchr(pythonioencoding, ':');
1557 if (errors) {
1558 *errors = '\0';
1559 errors++;
1560 if (!errors[0]) {
1561 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001562 }
1563 }
1564
1565 /* Does PYTHONIOENCODING contain an encoding? */
1566 if (pythonioencoding[0]) {
1567 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001568 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1569 pythonioencoding,
1570 "PYTHONIOENCODING environment variable");
1571 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001572 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001573 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001574 }
1575 }
1576
1577 /* If the encoding is set but not the error handler,
1578 use "strict" error handler by default.
1579 PYTHONIOENCODING=latin1 behaves as
1580 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001581 if (!errors) {
1582 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001583 }
1584 }
1585
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001586 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001587 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1588 errors,
1589 "PYTHONIOENCODING environment variable");
1590 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001591 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001592 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001593 }
1594 }
1595
1596 PyMem_RawFree(pythonioencoding);
1597 }
1598
1599 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001600 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001601 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001602 status = PyConfig_SetString(config, &config->stdio_encoding,
1603 L"utf-8");
1604 if (_PyStatus_EXCEPTION(status)) {
1605 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001606 }
1607 }
1608 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001609 status = PyConfig_SetString(config, &config->stdio_errors,
1610 L"surrogateescape");
1611 if (_PyStatus_EXCEPTION(status)) {
1612 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001613 }
1614 }
1615 }
1616
1617 /* Choose the default error handler based on the current locale. */
1618 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001619 status = config_get_locale_encoding(config, &config->stdio_encoding);
1620 if (_PyStatus_EXCEPTION(status)) {
1621 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001622 }
1623 }
1624 if (config->stdio_errors == NULL) {
Andy Lesteraa450a02020-03-07 11:36:04 -06001625 const wchar_t *errors = config_get_stdio_errors();
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001626 assert(errors != NULL);
1627
Victor Stinner331a6a52019-05-27 16:39:22 +02001628 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1629 if (_PyStatus_EXCEPTION(status)) {
1630 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001631 }
1632 }
1633
Victor Stinner331a6a52019-05-27 16:39:22 +02001634 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001635}
1636
1637
Victor Stinner331a6a52019-05-27 16:39:22 +02001638static PyStatus
1639config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001640{
Victor Stinner331a6a52019-05-27 16:39:22 +02001641 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001642
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001643 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001644#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001645 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001646#else
Victor Stinnere2510952019-05-02 11:28:57 -04001647
1648#ifdef MS_WINDOWS
1649 if (preconfig->legacy_windows_fs_encoding) {
1650 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001651 status = PyConfig_SetString(config, &config->filesystem_encoding,
1652 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001653 }
1654 else
1655#endif
Victor Stinner20004952019-03-26 02:31:11 +01001656 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001657 status = PyConfig_SetString(config, &config->filesystem_encoding,
1658 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001659 }
Victor Stinnere2510952019-05-02 11:28:57 -04001660#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001661 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001662 status = PyConfig_SetString(config, &config->filesystem_encoding,
1663 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001664 }
Victor Stinnere2510952019-05-02 11:28:57 -04001665#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001666 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001667#ifdef MS_WINDOWS
1668 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001669 status = PyConfig_SetString(config, &config->filesystem_encoding,
1670 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001671#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001672 status = config_get_locale_encoding(config,
1673 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001674#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001675 }
Victor Stinnere2510952019-05-02 11:28:57 -04001676#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001677
Victor Stinner331a6a52019-05-27 16:39:22 +02001678 if (_PyStatus_EXCEPTION(status)) {
1679 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001680 }
1681 }
1682
1683 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001684 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001685#ifdef MS_WINDOWS
1686 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001687 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001688 }
1689 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001690 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001691 }
1692#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001693 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001694#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001695 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1696 if (_PyStatus_EXCEPTION(status)) {
1697 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001698 }
1699 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001700 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001701}
1702
1703
Victor Stinner331a6a52019-05-27 16:39:22 +02001704static PyStatus
1705config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001706{
Victor Stinner331a6a52019-05-27 16:39:22 +02001707 PyStatus status;
1708 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001709
Victor Stinner20004952019-03-26 02:31:11 +01001710 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001711 status = config_read_env_vars(config);
1712 if (_PyStatus_EXCEPTION(status)) {
1713 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001714 }
1715 }
1716
1717 /* -X options */
1718 if (config_get_xoption(config, L"showrefcount")) {
1719 config->show_ref_count = 1;
1720 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001721
Victor Stinner331a6a52019-05-27 16:39:22 +02001722 status = config_read_complex_options(config);
1723 if (_PyStatus_EXCEPTION(status)) {
1724 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001725 }
1726
Victor Stinner6c785c02018-08-01 17:56:14 +02001727 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001728 status = config_init_home(config);
1729 if (_PyStatus_EXCEPTION(status)) {
1730 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001731 }
1732 }
1733
Steve Dower177a41a2018-11-17 20:41:48 -08001734 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001735 status = config_init_executable(config);
1736 if (_PyStatus_EXCEPTION(status)) {
1737 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001738 }
1739 }
1740
Sandro Mani8f023a22020-06-08 17:28:11 +02001741 if(config->platlibdir == NULL) {
1742 status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR,
1743 "PLATLIBDIR macro");
1744 if (_PyStatus_EXCEPTION(status)) {
1745 return status;
1746 }
1747 }
1748
Victor Stinner6c785c02018-08-01 17:56:14 +02001749 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001750 status = _PyConfig_InitPathConfig(config);
1751 if (_PyStatus_EXCEPTION(status)) {
1752 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001753 }
1754 }
1755
1756 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001757 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001758 if (config->faulthandler < 0) {
1759 config->faulthandler = 1;
1760 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001761 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001762 if (config->faulthandler < 0) {
1763 config->faulthandler = 0;
1764 }
1765 if (config->tracemalloc < 0) {
1766 config->tracemalloc = 0;
1767 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001768 if (config->use_hash_seed < 0) {
1769 config->use_hash_seed = 0;
1770 config->hash_seed = 0;
1771 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001772
Victor Stinner70fead22018-08-29 13:45:34 +02001773 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001774 status = config_init_fs_encoding(config, preconfig);
1775 if (_PyStatus_EXCEPTION(status)) {
1776 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001777 }
1778 }
1779
Victor Stinner331a6a52019-05-27 16:39:22 +02001780 status = config_init_stdio_encoding(config, preconfig);
1781 if (_PyStatus_EXCEPTION(status)) {
1782 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001783 }
1784
Victor Stinner62599762019-03-15 16:03:23 +01001785 if (config->argv.length < 1) {
1786 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001787 status = PyWideStringList_Append(&config->argv, L"");
1788 if (_PyStatus_EXCEPTION(status)) {
1789 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001790 }
1791 }
Victor Stinner870b0352019-05-17 03:15:12 +02001792
1793 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001794 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1795 L"default");
1796 if (_PyStatus_EXCEPTION(status)) {
1797 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001798 }
1799 }
1800
1801 if (config->configure_c_stdio < 0) {
1802 config->configure_c_stdio = 1;
1803 }
1804
Victor Stinner331a6a52019-05-27 16:39:22 +02001805 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001806}
Victor Stinner5ed69952018-11-06 15:59:52 +01001807
1808
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001809static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001810config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001811{
1812#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1813 /* don't translate newlines (\r\n <=> \n) */
1814 _setmode(fileno(stdin), O_BINARY);
1815 _setmode(fileno(stdout), O_BINARY);
1816 _setmode(fileno(stderr), O_BINARY);
1817#endif
1818
1819 if (!config->buffered_stdio) {
1820#ifdef HAVE_SETVBUF
1821 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1822 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1823 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1824#else /* !HAVE_SETVBUF */
1825 setbuf(stdin, (char *)NULL);
1826 setbuf(stdout, (char *)NULL);
1827 setbuf(stderr, (char *)NULL);
1828#endif /* !HAVE_SETVBUF */
1829 }
1830 else if (config->interactive) {
1831#ifdef MS_WINDOWS
1832 /* Doesn't have to have line-buffered -- use unbuffered */
1833 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1834 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1835#else /* !MS_WINDOWS */
1836#ifdef HAVE_SETVBUF
1837 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1838 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1839#endif /* HAVE_SETVBUF */
1840#endif /* !MS_WINDOWS */
1841 /* Leave stderr alone - it should be unbuffered anyway. */
1842 }
1843}
1844
1845
1846/* Write the configuration:
1847
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001848 - set Py_xxx global configuration variables
1849 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinnere81f6e62020-06-08 18:12:59 +02001850PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +02001851_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001852{
Victor Stinner331a6a52019-05-27 16:39:22 +02001853 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001854
1855 if (config->configure_c_stdio) {
1856 config_init_stdio(config);
1857 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001858
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001859 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001860 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001861 preconfig->isolated = config->isolated;
1862 preconfig->use_environment = config->use_environment;
1863 preconfig->dev_mode = config->dev_mode;
Victor Stinnere81f6e62020-06-08 18:12:59 +02001864
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02001865 if (_Py_SetArgcArgv(config->orig_argv.length,
1866 config->orig_argv.items) < 0)
Victor Stinnere81f6e62020-06-08 18:12:59 +02001867 {
1868 return _PyStatus_NO_MEMORY();
1869 }
1870 return _PyStatus_OK();
Victor Stinner5ed69952018-11-06 15:59:52 +01001871}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001872
1873
Victor Stinner331a6a52019-05-27 16:39:22 +02001874/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001875
1876static void
Victor Stinner2f549082019-03-29 15:13:46 +01001877config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001878{
Victor Stinner2f549082019-03-29 15:13:46 +01001879 FILE *f = error ? stderr : stdout;
1880
1881 fprintf(f, usage_line, program);
1882 if (error)
1883 fprintf(f, "Try `python -h' for more information.\n");
1884 else {
1885 fputs(usage_1, f);
1886 fputs(usage_2, f);
1887 fputs(usage_3, f);
1888 fprintf(f, usage_4, (wint_t)DELIM);
1889 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1890 fputs(usage_6, f);
1891 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001892}
1893
1894
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001895/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001896static PyStatus
1897config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001898 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001899{
Victor Stinner331a6a52019-05-27 16:39:22 +02001900 PyStatus status;
1901 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001902 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001903 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001904
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001905 _PyOS_ResetGetOpt();
1906 do {
1907 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001908 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001909 if (c == EOF) {
1910 break;
1911 }
1912
1913 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001914 if (config->run_command == NULL) {
1915 /* -c is the last option; following arguments
1916 that look like options are left for the
1917 command to interpret. */
1918 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1919 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1920 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001921 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001922 }
1923 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1924 command[len - 2] = '\n';
1925 command[len - 1] = 0;
1926 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001927 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001928 break;
1929 }
1930
1931 if (c == 'm') {
1932 /* -m is the last option; following arguments
1933 that look like options are left for the
1934 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001935 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001936 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1937 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001938 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001939 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001940 }
1941 break;
1942 }
1943
1944 switch (c) {
1945 case 0:
1946 // Handle long option.
1947 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001948 if (wcscmp(_PyOS_optarg, L"always") == 0
1949 || wcscmp(_PyOS_optarg, L"never") == 0
1950 || wcscmp(_PyOS_optarg, L"default") == 0)
1951 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001952 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1953 _PyOS_optarg);
1954 if (_PyStatus_EXCEPTION(status)) {
1955 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001956 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001957 } else {
1958 fprintf(stderr, "--check-hash-based-pycs must be one of "
1959 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001960 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001961 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001962 }
1963 break;
1964
1965 case 'b':
1966 config->bytes_warning++;
1967 break;
1968
1969 case 'd':
1970 config->parser_debug++;
1971 break;
1972
1973 case 'i':
1974 config->inspect++;
1975 config->interactive++;
1976 break;
1977
Victor Stinner6dcb5422019-03-05 02:44:12 +01001978 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001979 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001980 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001981 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001982 break;
1983
1984 /* case 'J': reserved for Jython */
1985
1986 case 'O':
1987 config->optimization_level++;
1988 break;
1989
1990 case 'B':
1991 config->write_bytecode = 0;
1992 break;
1993
1994 case 's':
1995 config->user_site_directory = 0;
1996 break;
1997
1998 case 'S':
1999 config->site_import = 0;
2000 break;
2001
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002002 case 't':
2003 /* ignored for backwards compatibility */
2004 break;
2005
2006 case 'u':
2007 config->buffered_stdio = 0;
2008 break;
2009
2010 case 'v':
2011 config->verbose++;
2012 break;
2013
2014 case 'x':
2015 config->skip_source_first_line = 1;
2016 break;
2017
2018 case 'h':
2019 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02002020 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002021 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002022
2023 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01002024 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002025 break;
2026
2027 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002028 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2029 if (_PyStatus_EXCEPTION(status)) {
2030 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002031 }
2032 break;
2033
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002034 case 'q':
2035 config->quiet++;
2036 break;
2037
2038 case 'R':
2039 config->use_hash_seed = 0;
2040 break;
2041
2042 /* This space reserved for other options */
2043
2044 default:
2045 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002046 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002047 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002048 }
2049 } while (1);
2050
Victor Stinner2f549082019-03-29 15:13:46 +01002051 if (print_version) {
2052 printf("Python %s\n",
2053 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002054 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002055 }
2056
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002057 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002058 && _PyOS_optind < argv->length
2059 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002060 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002061 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002062 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002063 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002064 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002065 }
2066 }
2067
2068 if (config->run_command != NULL || config->run_module != NULL) {
2069 /* Backup _PyOS_optind */
2070 _PyOS_optind--;
2071 }
2072
Victor Stinnerae239f62019-05-16 17:02:56 +02002073 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002074
Victor Stinner331a6a52019-05-27 16:39:22 +02002075 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002076}
2077
2078
2079#ifdef MS_WINDOWS
2080# define WCSTOK wcstok_s
2081#else
2082# define WCSTOK wcstok
2083#endif
2084
2085/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002086static PyStatus
2087config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002088{
Victor Stinner331a6a52019-05-27 16:39:22 +02002089 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002090 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2091 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002092 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002093 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002094 if (_PyStatus_EXCEPTION(status)) {
2095 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002096 }
2097
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002098 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002099 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002100 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002101 }
2102
2103
2104 wchar_t *warning, *context = NULL;
2105 for (warning = WCSTOK(env, L",", &context);
2106 warning != NULL;
2107 warning = WCSTOK(NULL, L",", &context))
2108 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002109 status = PyWideStringList_Append(warnoptions, warning);
2110 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002111 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002112 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002113 }
2114 }
2115 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002116 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002117}
2118
2119
Victor Stinner331a6a52019-05-27 16:39:22 +02002120static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002121warnoptions_append(PyConfig *config, PyWideStringList *options,
2122 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002123{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002124 /* config_init_warnoptions() add existing config warnoptions at the end:
2125 ensure that the new option is not already present in this list to
2126 prevent change the options order whne config_init_warnoptions() is
2127 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002128 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002129 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002130 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002131 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002132 if (_PyWideStringList_Find(options, option)) {
2133 /* Already present: do nothing */
2134 return _PyStatus_OK();
2135 }
2136 return PyWideStringList_Append(options, option);
2137}
2138
2139
2140static PyStatus
2141warnoptions_extend(PyConfig *config, PyWideStringList *options,
2142 const PyWideStringList *options2)
2143{
2144 const Py_ssize_t len = options2->length;
2145 wchar_t *const *items = options2->items;
2146
2147 for (Py_ssize_t i = 0; i < len; i++) {
2148 PyStatus status = warnoptions_append(config, options, items[i]);
2149 if (_PyStatus_EXCEPTION(status)) {
2150 return status;
2151 }
2152 }
2153 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002154}
2155
2156
Victor Stinner331a6a52019-05-27 16:39:22 +02002157static PyStatus
2158config_init_warnoptions(PyConfig *config,
2159 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002160 const PyWideStringList *env_warnoptions,
2161 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002162{
Victor Stinner331a6a52019-05-27 16:39:22 +02002163 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002164 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002165
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002166 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002167 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002168 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002169 * - PyConfig.dev_mode: "default" filter
2170 * - PYTHONWARNINGS environment variable
2171 * - '-W' command line options
2172 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2173 * "default::BytesWarning" or "error::BytesWarning" filter
2174 * - early PySys_AddWarnOption() calls
2175 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002176 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002177 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2178 * module works on the basis of "the most recently added filter will be
2179 * checked first", we add the lowest precedence entries first so that later
2180 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002181 */
2182
Victor Stinner20004952019-03-26 02:31:11 +01002183 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002184 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002185 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002186 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002187 }
2188 }
2189
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002190 status = warnoptions_extend(config, &options, env_warnoptions);
2191 if (_PyStatus_EXCEPTION(status)) {
2192 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002193 }
2194
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002195 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2196 if (_PyStatus_EXCEPTION(status)) {
2197 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002198 }
2199
2200 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2201 * don't even try to emit a warning, so we skip setting the filter in that
2202 * case.
2203 */
2204 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002205 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002206 if (config->bytes_warning> 1) {
2207 filter = L"error::BytesWarning";
2208 }
2209 else {
2210 filter = L"default::BytesWarning";
2211 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002212 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002213 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002214 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002215 }
2216 }
Victor Stinner120b7072019-08-23 18:03:08 +01002217
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002218 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002219 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002220 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002221 }
2222
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002223 /* Always add all PyConfig.warnoptions options */
2224 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2225 if (_PyStatus_EXCEPTION(status)) {
2226 goto error;
2227 }
2228
2229 _PyWideStringList_Clear(&config->warnoptions);
2230 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002231 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002232
2233error:
2234 _PyWideStringList_Clear(&options);
2235 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002236}
2237
2238
Victor Stinner331a6a52019-05-27 16:39:22 +02002239static PyStatus
2240config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002241{
Victor Stinner331a6a52019-05-27 16:39:22 +02002242 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002243 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002244
Victor Stinner74f65682019-03-15 15:08:05 +01002245 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002246 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002247 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002248 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2249 if (_PyStatus_EXCEPTION(status)) {
2250 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002251 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002252 }
2253 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002254 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002255 slice.length = cmdline_argv->length - opt_index;
2256 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002257 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2258 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002259 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002260 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002261 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002262
2263 wchar_t *arg0 = NULL;
2264 if (config->run_command != NULL) {
2265 /* Force sys.argv[0] = '-c' */
2266 arg0 = L"-c";
2267 }
2268 else if (config->run_module != NULL) {
2269 /* Force sys.argv[0] = '-m'*/
2270 arg0 = L"-m";
2271 }
Victor Stinner3939c322019-06-25 15:02:43 +02002272
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002273 if (arg0 != NULL) {
2274 arg0 = _PyMem_RawWcsdup(arg0);
2275 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002276 _PyWideStringList_Clear(&config_argv);
2277 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002278 }
2279
Victor Stinnerfa153762019-03-20 04:25:38 +01002280 PyMem_RawFree(config_argv.items[0]);
2281 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002282 }
2283
Victor Stinner331a6a52019-05-27 16:39:22 +02002284 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002285 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002286 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002287}
2288
2289
Victor Stinner331a6a52019-05-27 16:39:22 +02002290static PyStatus
2291core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002292{
Victor Stinner331a6a52019-05-27 16:39:22 +02002293 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002294
Victor Stinnercab5d072019-05-17 19:01:14 +02002295 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002296 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2297 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002298 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002299 }
2300
Victor Stinner331a6a52019-05-27 16:39:22 +02002301 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002302
2303 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2304 if (_PyStatus_EXCEPTION(status)) {
2305 return status;
2306 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002307
Victor Stinner331a6a52019-05-27 16:39:22 +02002308 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002309
Victor Stinner331a6a52019-05-27 16:39:22 +02002310 status = _PyPreCmdline_Read(precmdline, &preconfig);
2311 if (_PyStatus_EXCEPTION(status)) {
2312 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002313 }
2314
Victor Stinner331a6a52019-05-27 16:39:22 +02002315 status = _PyPreCmdline_SetConfig(precmdline, config);
2316 if (_PyStatus_EXCEPTION(status)) {
2317 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002318 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002319 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002320}
2321
2322
Victor Stinner3939c322019-06-25 15:02:43 +02002323/* Get run_filename absolute path */
2324static PyStatus
2325config_run_filename_abspath(PyConfig *config)
2326{
2327 if (!config->run_filename) {
2328 return _PyStatus_OK();
2329 }
2330
2331#ifndef MS_WINDOWS
2332 if (_Py_isabs(config->run_filename)) {
2333 /* path is already absolute */
2334 return _PyStatus_OK();
2335 }
2336#endif
2337
2338 wchar_t *abs_filename;
2339 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2340 /* failed to get the absolute path of the command line filename:
2341 ignore the error, keep the relative path */
2342 return _PyStatus_OK();
2343 }
2344 if (abs_filename == NULL) {
2345 return _PyStatus_NO_MEMORY();
2346 }
2347
2348 PyMem_RawFree(config->run_filename);
2349 config->run_filename = abs_filename;
2350 return _PyStatus_OK();
2351}
2352
2353
Victor Stinner331a6a52019-05-27 16:39:22 +02002354static PyStatus
2355config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002356{
Victor Stinner331a6a52019-05-27 16:39:22 +02002357 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002358 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2359 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2360 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002361
Victor Stinnerae239f62019-05-16 17:02:56 +02002362 if (config->parse_argv < 0) {
2363 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002364 }
Victor Stinner870b0352019-05-17 03:15:12 +02002365
Victor Stinnerfed02e12019-05-17 11:12:09 +02002366 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002367 status = config_init_program_name(config);
2368 if (_PyStatus_EXCEPTION(status)) {
2369 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002370 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002371 }
Victor Stinner2f549082019-03-29 15:13:46 +01002372
Victor Stinnerae239f62019-05-16 17:02:56 +02002373 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002374 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002375 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2376 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002377 goto done;
2378 }
2379
Victor Stinner3939c322019-06-25 15:02:43 +02002380 status = config_run_filename_abspath(config);
2381 if (_PyStatus_EXCEPTION(status)) {
2382 goto done;
2383 }
2384
Victor Stinner331a6a52019-05-27 16:39:22 +02002385 status = config_update_argv(config, opt_index);
2386 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002387 goto done;
2388 }
Victor Stinner2f549082019-03-29 15:13:46 +01002389 }
Victor Stinner3939c322019-06-25 15:02:43 +02002390 else {
2391 status = config_run_filename_abspath(config);
2392 if (_PyStatus_EXCEPTION(status)) {
2393 goto done;
2394 }
2395 }
Victor Stinner2f549082019-03-29 15:13:46 +01002396
Victor Stinner2f549082019-03-29 15:13:46 +01002397 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002398 status = config_init_env_warnoptions(config, &env_warnoptions);
2399 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002400 goto done;
2401 }
2402 }
2403
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002404 /* Handle early PySys_AddWarnOption() calls */
2405 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2406 if (_PyStatus_EXCEPTION(status)) {
2407 goto done;
2408 }
2409
Victor Stinner331a6a52019-05-27 16:39:22 +02002410 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002411 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002412 &env_warnoptions,
2413 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002414 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002415 goto done;
2416 }
2417
Victor Stinner331a6a52019-05-27 16:39:22 +02002418 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002419
2420done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002421 _PyWideStringList_Clear(&cmdline_warnoptions);
2422 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002423 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002424 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002425}
2426
2427
Victor Stinner331a6a52019-05-27 16:39:22 +02002428PyStatus
2429_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002430{
Victor Stinner331a6a52019-05-27 16:39:22 +02002431 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2432 if (_PyStatus_EXCEPTION(status)) {
2433 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002434 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002435
Victor Stinner5f38b842019-05-01 02:30:12 +02002436 return _PyArgv_AsWstrList(args, &config->argv);
2437}
2438
2439
Victor Stinner70005ac2019-05-02 15:25:34 -04002440/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2441 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002442PyStatus
2443PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002444{
2445 _PyArgv args = {
2446 .argc = argc,
2447 .use_bytes_argv = 1,
2448 .bytes_argv = argv,
2449 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002450 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002451}
2452
2453
Victor Stinner331a6a52019-05-27 16:39:22 +02002454PyStatus
2455PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002456{
2457 _PyArgv args = {
2458 .argc = argc,
2459 .use_bytes_argv = 0,
2460 .bytes_argv = NULL,
2461 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002462 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002463}
2464
2465
Victor Stinner36242fd2019-07-01 19:13:50 +02002466PyStatus
2467PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2468 Py_ssize_t length, wchar_t **items)
2469{
2470 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2471 if (_PyStatus_EXCEPTION(status)) {
2472 return status;
2473 }
2474
2475 PyWideStringList list2 = {.length = length, .items = items};
2476 if (_PyWideStringList_Copy(list, &list2) < 0) {
2477 return _PyStatus_NO_MEMORY();
2478 }
2479 return _PyStatus_OK();
2480}
2481
2482
Victor Stinner331a6a52019-05-27 16:39:22 +02002483/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002484
2485 * Command line arguments
2486 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002487 * Py_xxx global configuration variables
2488
2489 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002490PyStatus
2491PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002492{
Victor Stinner331a6a52019-05-27 16:39:22 +02002493 PyStatus status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002494
Victor Stinner331a6a52019-05-27 16:39:22 +02002495 status = _Py_PreInitializeFromConfig(config, NULL);
2496 if (_PyStatus_EXCEPTION(status)) {
2497 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002498 }
2499
Victor Stinner331a6a52019-05-27 16:39:22 +02002500 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002501
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002502 if (config->orig_argv.length == 0
Victor Stinnere81f6e62020-06-08 18:12:59 +02002503 && !(config->argv.length == 1
2504 && wcscmp(config->argv.items[0], L"") == 0))
2505 {
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002506 if (_PyWideStringList_Copy(&config->orig_argv, &config->argv) < 0) {
Victor Stinnere81f6e62020-06-08 18:12:59 +02002507 return _PyStatus_NO_MEMORY();
2508 }
Victor Stinnercab5d072019-05-17 19:01:14 +02002509 }
2510
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002511 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002512 status = core_read_precmdline(config, &precmdline);
2513 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002514 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002515 }
2516
Victor Stinner870b0352019-05-17 03:15:12 +02002517 assert(config->isolated >= 0);
2518 if (config->isolated) {
2519 config->use_environment = 0;
2520 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002521 }
2522
Victor Stinner331a6a52019-05-27 16:39:22 +02002523 status = config_read_cmdline(config);
2524 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002525 goto done;
2526 }
2527
Victor Stinner120b7072019-08-23 18:03:08 +01002528 /* Handle early PySys_AddXOption() calls */
2529 status = _PySys_ReadPreinitXOptions(config);
2530 if (_PyStatus_EXCEPTION(status)) {
2531 goto done;
2532 }
2533
Victor Stinner331a6a52019-05-27 16:39:22 +02002534 status = config_read(config);
2535 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002536 goto done;
2537 }
2538
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002539 /* Check config consistency */
2540 assert(config->isolated >= 0);
2541 assert(config->use_environment >= 0);
2542 assert(config->dev_mode >= 0);
2543 assert(config->install_signal_handlers >= 0);
2544 assert(config->use_hash_seed >= 0);
2545 assert(config->faulthandler >= 0);
2546 assert(config->tracemalloc >= 0);
2547 assert(config->site_import >= 0);
2548 assert(config->bytes_warning >= 0);
2549 assert(config->inspect >= 0);
2550 assert(config->interactive >= 0);
2551 assert(config->optimization_level >= 0);
2552 assert(config->parser_debug >= 0);
2553 assert(config->write_bytecode >= 0);
2554 assert(config->verbose >= 0);
2555 assert(config->quiet >= 0);
2556 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002557 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002558 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002559 assert(config->buffered_stdio >= 0);
2560 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002561 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002562 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2563 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002564 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2565 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2566 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002567 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002568 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002569 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002570 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002571 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002572 assert(config->prefix != NULL);
2573 assert(config->base_prefix != NULL);
2574 assert(config->exec_prefix != NULL);
2575 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002576 }
Sandro Mani8f023a22020-06-08 17:28:11 +02002577 assert(config->platlibdir != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002578 assert(config->filesystem_encoding != NULL);
2579 assert(config->filesystem_errors != NULL);
2580 assert(config->stdio_encoding != NULL);
2581 assert(config->stdio_errors != NULL);
2582#ifdef MS_WINDOWS
2583 assert(config->legacy_windows_stdio >= 0);
2584#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002585 /* -c and -m options are exclusive */
2586 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002587 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002588 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002589 assert(config->pathconfig_warnings >= 0);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002590 assert(_PyWideStringList_CheckConsistency(&config->orig_argv));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002591
Victor Stinner331a6a52019-05-27 16:39:22 +02002592 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002593
2594done:
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002595 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002596 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002597}
Victor Stinner1075d162019-03-25 23:19:57 +01002598
2599
2600PyObject*
2601_Py_GetConfigsAsDict(void)
2602{
Victor Stinner331a6a52019-05-27 16:39:22 +02002603 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002604 PyObject *dict = NULL;
2605
Victor Stinner331a6a52019-05-27 16:39:22 +02002606 result = PyDict_New();
2607 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002608 goto error;
2609 }
2610
Victor Stinner331a6a52019-05-27 16:39:22 +02002611 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002612 dict = _Py_GetGlobalVariablesAsDict();
2613 if (dict == NULL) {
2614 goto error;
2615 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002616 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002617 goto error;
2618 }
2619 Py_CLEAR(dict);
2620
2621 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002622 PyThreadState *tstate = _PyThreadState_GET();
2623 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002624 dict = _PyPreConfig_AsDict(pre_config);
2625 if (dict == NULL) {
2626 goto error;
2627 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002628 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002629 goto error;
2630 }
2631 Py_CLEAR(dict);
2632
2633 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002634 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinner331a6a52019-05-27 16:39:22 +02002635 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002636 if (dict == NULL) {
2637 goto error;
2638 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002639 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002640 goto error;
2641 }
2642 Py_CLEAR(dict);
2643
Victor Stinner8f427482020-07-08 00:20:37 +02002644 /* path config */
2645 dict = _PyPathConfig_AsDict();
2646 if (dict == NULL) {
2647 goto error;
2648 }
2649 if (PyDict_SetItemString(result, "path_config", dict) < 0) {
2650 goto error;
2651 }
2652 Py_CLEAR(dict);
2653
Victor Stinner331a6a52019-05-27 16:39:22 +02002654 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002655
2656error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002657 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002658 Py_XDECREF(dict);
2659 return NULL;
2660}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002661
2662
2663static void
2664init_dump_ascii_wstr(const wchar_t *str)
2665{
2666 if (str == NULL) {
2667 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002668 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002669 }
2670
2671 PySys_WriteStderr("'");
2672 for (; *str != L'\0'; str++) {
Victor Stinner640e8e12020-09-09 12:07:17 +02002673 unsigned int ch = (unsigned int)*str;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002674 if (ch == L'\'') {
2675 PySys_WriteStderr("\\'");
2676 } else if (0x20 <= ch && ch < 0x7f) {
2677 PySys_WriteStderr("%lc", ch);
2678 }
2679 else if (ch <= 0xff) {
2680 PySys_WriteStderr("\\x%02x", ch);
2681 }
2682#if SIZEOF_WCHAR_T > 2
2683 else if (ch > 0xffff) {
2684 PySys_WriteStderr("\\U%08x", ch);
2685 }
2686#endif
2687 else {
2688 PySys_WriteStderr("\\u%04x", ch);
2689 }
2690 }
2691 PySys_WriteStderr("'");
2692}
2693
2694
2695/* Dump the Python path configuration into sys.stderr */
2696void
2697_Py_DumpPathConfig(PyThreadState *tstate)
2698{
2699 PyObject *exc_type, *exc_value, *exc_tb;
2700 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2701
2702 PySys_WriteStderr("Python path configuration:\n");
2703
2704#define DUMP_CONFIG(NAME, FIELD) \
2705 do { \
2706 PySys_WriteStderr(" " NAME " = "); \
2707 init_dump_ascii_wstr(config->FIELD); \
2708 PySys_WriteStderr("\n"); \
2709 } while (0)
2710
Victor Stinnerda7933e2020-04-13 03:04:28 +02002711 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002712 DUMP_CONFIG("PYTHONHOME", home);
2713 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2714 DUMP_CONFIG("program name", program_name);
2715 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2716 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2717 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2718 PySys_WriteStderr(" import site = %i\n", config->site_import);
2719#undef DUMP_CONFIG
2720
2721#define DUMP_SYS(NAME) \
2722 do { \
2723 obj = PySys_GetObject(#NAME); \
2724 PySys_FormatStderr(" sys.%s = ", #NAME); \
2725 if (obj != NULL) { \
2726 PySys_FormatStderr("%A", obj); \
2727 } \
2728 else { \
2729 PySys_WriteStderr("(not set)"); \
2730 } \
2731 PySys_FormatStderr("\n"); \
2732 } while (0)
2733
2734 PyObject *obj;
2735 DUMP_SYS(_base_executable);
2736 DUMP_SYS(base_prefix);
2737 DUMP_SYS(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +02002738 DUMP_SYS(platlibdir);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002739 DUMP_SYS(executable);
2740 DUMP_SYS(prefix);
2741 DUMP_SYS(exec_prefix);
2742#undef DUMP_SYS
2743
2744 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2745 if (sys_path != NULL && PyList_Check(sys_path)) {
2746 PySys_WriteStderr(" sys.path = [\n");
2747 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2748 for (Py_ssize_t i=0; i < len; i++) {
2749 PyObject *path = PyList_GET_ITEM(sys_path, i);
2750 PySys_FormatStderr(" %A,\n", path);
2751 }
2752 PySys_WriteStderr(" ]\n");
2753 }
2754
2755 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2756}