blob: c313d91ac7309c778b791260f56a1e6580739c9d [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
Victor Stinner6c785c02018-08-01 17:56:14 +020027
Victor Stinner95e2cbf2019-03-01 16:25:19 +010028/* --- Command line options --------------------------------------- */
29
Victor Stinner95e2cbf2019-03-01 16:25:19 +010030/* Short usage message (with %s for argv0) */
31static const char usage_line[] =
32"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
33
34/* Long usage message, split into parts < 512 bytes */
35static const char usage_1[] = "\
36Options and arguments (and corresponding environment variables):\n\
37-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
38 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
39-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
40-c cmd : program passed in as string (terminates option list)\n\
41-d : debug output from parser; also PYTHONDEBUG=x\n\
42-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
43-h : print this help message and exit (also --help)\n\
44";
45static const char usage_2[] = "\
46-i : inspect interactively after running script; forces a prompt even\n\
47 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
48-I : isolate Python from the user's environment (implies -E and -s)\n\
49-m mod : run library module as a script (terminates option list)\n\
50-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
51 .pyc extension; also PYTHONOPTIMIZE=x\n\
52-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
53 .pyc extension\n\
54-q : don't print version and copyright messages on interactive startup\n\
55-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
56-S : don't imply 'import site' on initialization\n\
57";
58static const char usage_3[] = "\
59-u : force the stdout and stderr streams to be unbuffered;\n\
60 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
61-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
62 can be supplied multiple times to increase verbosity\n\
63-V : print the Python version number and exit (also --version)\n\
64 when given twice, print more information about the build\n\
65-W arg : warning control; arg is action:message:category:module:lineno\n\
66 also PYTHONWARNINGS=arg\n\
67-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000068-X opt : set implementation-specific option. The following options are available:\n\
69\n\
70 -X faulthandler: enable faulthandler\n\
71 -X showrefcount: output the total reference count and number of used\n\
72 memory blocks when the program finishes or after each statement in the\n\
73 interactive interpreter. This only works on debug builds\n\
74 -X tracemalloc: start tracing Python memory allocations using the\n\
75 tracemalloc module. By default, only the most recent frame is stored in a\n\
76 traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\
77 traceback limit of NFRAME frames\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000078 -X importtime: show how long each import takes. It shows module name,\n\
79 cumulative time (including nested imports) and self time (excluding\n\
80 nested imports). Note that its output may be broken in multi-threaded\n\
81 application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
82 -X dev: enable CPythons development mode”, introducing additional runtime\n\
83 checks which are too expensive to be enabled by default. Effect of the\n\
84 developer mode:\n\
85 * Add default warning filter, as -W default\n\
86 * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\
87 * Enable the faulthandler module to dump the Python traceback on a crash\n\
88 * Enable asyncio debug mode\n\
89 * Set the dev_mode attribute of sys.flags to True\n\
90 * io.IOBase destructor logs close() exceptions\n\
91 -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\
92 locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\
93 otherwise activate automatically)\n\
94 -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
95 given directory instead of to the code tree\n\
96\n\
Victor Stinner95e2cbf2019-03-01 16:25:19 +010097--check-hash-based-pycs always|default|never:\n\
98 control how Python invalidates hash-based .pyc files\n\
99";
100static const char usage_4[] = "\
101file : program read from script file\n\
102- : program read from stdin (default; interactive mode if a tty)\n\
103arg ...: arguments passed to program in sys.argv[1:]\n\n\
104Other environment variables:\n\
105PYTHONSTARTUP: file executed on interactive startup (no default)\n\
106PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
107 default module search path. The result is sys.path.\n\
108";
109static const char usage_5[] =
110"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
111" The default module search path uses %s.\n"
112"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
Inada Naoki95826c72019-12-14 14:27:32 +0900113"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100114"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
115"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
116static const char usage_6[] =
117"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Serhiy Storchakae9c90aa2019-08-24 12:49:27 +0300118" to seed the hashes of str and bytes objects. It can also be set to an\n"
119" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100120" predictable seed.\n"
121"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
122" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
123" hooks.\n"
124"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
125" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
126" locale coercion and locale compatibility warnings on stderr.\n"
127"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
128" debugger. It can be set to the callable of your debugger of choice.\n"
129"PYTHONDEVMODE: enable the development mode.\n"
130"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
131
132#if defined(MS_WINDOWS)
133# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
134#else
135# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
136#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200137
138
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100139/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200140
Victor Stinner6c785c02018-08-01 17:56:14 +0200141/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200142 stdin and stdout error handler to "surrogateescape". */
143int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200144int Py_DebugFlag = 0; /* Needed by parser.c */
145int Py_VerboseFlag = 0; /* Needed by import.c */
146int Py_QuietFlag = 0; /* Needed by sysmodule.c */
147int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
148int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
149int Py_OptimizeFlag = 0; /* Needed by compile.c */
150int Py_NoSiteFlag = 0; /* Suppress 'import site' */
151int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
152int Py_FrozenFlag = 0; /* Needed by getpath.c */
153int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
154int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
155int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
156int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
157int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
158int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
159#ifdef MS_WINDOWS
160int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
161int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
162#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200163
164
Victor Stinner1075d162019-03-25 23:19:57 +0100165static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100166_Py_GetGlobalVariablesAsDict(void)
167{
168 PyObject *dict, *obj;
169
170 dict = PyDict_New();
171 if (dict == NULL) {
172 return NULL;
173 }
174
175#define SET_ITEM(KEY, EXPR) \
176 do { \
177 obj = (EXPR); \
178 if (obj == NULL) { \
179 return NULL; \
180 } \
181 int res = PyDict_SetItemString(dict, (KEY), obj); \
182 Py_DECREF(obj); \
183 if (res < 0) { \
184 goto fail; \
185 } \
186 } while (0)
187#define SET_ITEM_INT(VAR) \
188 SET_ITEM(#VAR, PyLong_FromLong(VAR))
189#define FROM_STRING(STR) \
190 ((STR != NULL) ? \
191 PyUnicode_FromString(STR) \
192 : (Py_INCREF(Py_None), Py_None))
193#define SET_ITEM_STR(VAR) \
194 SET_ITEM(#VAR, FROM_STRING(VAR))
195
196 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
197 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
198 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
199 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
200
201 SET_ITEM_INT(Py_UTF8Mode);
202 SET_ITEM_INT(Py_DebugFlag);
203 SET_ITEM_INT(Py_VerboseFlag);
204 SET_ITEM_INT(Py_QuietFlag);
205 SET_ITEM_INT(Py_InteractiveFlag);
206 SET_ITEM_INT(Py_InspectFlag);
207
208 SET_ITEM_INT(Py_OptimizeFlag);
209 SET_ITEM_INT(Py_NoSiteFlag);
210 SET_ITEM_INT(Py_BytesWarningFlag);
211 SET_ITEM_INT(Py_FrozenFlag);
212 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
213 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
214 SET_ITEM_INT(Py_NoUserSiteDirectory);
215 SET_ITEM_INT(Py_UnbufferedStdioFlag);
216 SET_ITEM_INT(Py_HashRandomizationFlag);
217 SET_ITEM_INT(Py_IsolatedFlag);
218
219#ifdef MS_WINDOWS
220 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
221 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
222#endif
223
224 return dict;
225
226fail:
227 Py_DECREF(dict);
228 return NULL;
229
230#undef FROM_STRING
231#undef SET_ITEM
232#undef SET_ITEM_INT
233#undef SET_ITEM_STR
234}
235
236
Victor Stinner331a6a52019-05-27 16:39:22 +0200237/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200238
Victor Stinner331a6a52019-05-27 16:39:22 +0200239PyStatus PyStatus_Ok(void)
240{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200241
Victor Stinner331a6a52019-05-27 16:39:22 +0200242PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200243{
Victor Stinner331a6a52019-05-27 16:39:22 +0200244 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner871ff772019-05-17 23:54:00 +0200245 .err_msg = err_msg};
246}
247
Victor Stinner331a6a52019-05-27 16:39:22 +0200248PyStatus PyStatus_NoMemory(void)
249{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200250
Victor Stinner331a6a52019-05-27 16:39:22 +0200251PyStatus PyStatus_Exit(int exitcode)
252{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200253
254
Victor Stinner331a6a52019-05-27 16:39:22 +0200255int PyStatus_IsError(PyStatus status)
256{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200257
Victor Stinner331a6a52019-05-27 16:39:22 +0200258int PyStatus_IsExit(PyStatus status)
259{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200260
Victor Stinner331a6a52019-05-27 16:39:22 +0200261int PyStatus_Exception(PyStatus status)
262{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200263
264
Victor Stinner331a6a52019-05-27 16:39:22 +0200265/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100266
267#ifndef NDEBUG
268int
Victor Stinner331a6a52019-05-27 16:39:22 +0200269_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100270{
271 assert(list->length >= 0);
272 if (list->length != 0) {
273 assert(list->items != NULL);
274 }
275 for (Py_ssize_t i = 0; i < list->length; i++) {
276 assert(list->items[i] != NULL);
277 }
278 return 1;
279}
280#endif /* Py_DEBUG */
281
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100282
Victor Stinner6c785c02018-08-01 17:56:14 +0200283void
Victor Stinner331a6a52019-05-27 16:39:22 +0200284_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200285{
Victor Stinner331a6a52019-05-27 16:39:22 +0200286 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100287 for (Py_ssize_t i=0; i < list->length; i++) {
288 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200289 }
Victor Stinner74f65682019-03-15 15:08:05 +0100290 PyMem_RawFree(list->items);
291 list->length = 0;
292 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200293}
294
295
Victor Stinner74f65682019-03-15 15:08:05 +0100296int
Victor Stinner331a6a52019-05-27 16:39:22 +0200297_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200298{
Victor Stinner331a6a52019-05-27 16:39:22 +0200299 assert(_PyWideStringList_CheckConsistency(list));
300 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100301
302 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200303 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100304 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300305 }
Victor Stinner74f65682019-03-15 15:08:05 +0100306
Victor Stinnerfb4ae152019-09-30 01:40:17 +0200307 PyWideStringList copy = _PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100308
309 size_t size = list2->length * sizeof(list2->items[0]);
310 copy.items = PyMem_RawMalloc(size);
311 if (copy.items == NULL) {
312 return -1;
313 }
314
315 for (Py_ssize_t i=0; i < list2->length; i++) {
316 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
317 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200318 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100319 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200320 }
Victor Stinner74f65682019-03-15 15:08:05 +0100321 copy.items[i] = item;
322 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200323 }
Victor Stinner74f65682019-03-15 15:08:05 +0100324
Victor Stinner331a6a52019-05-27 16:39:22 +0200325 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100326 *list = copy;
327 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200328}
329
330
Victor Stinner331a6a52019-05-27 16:39:22 +0200331PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100332PyWideStringList_Insert(PyWideStringList *list,
333 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100334{
Victor Stinner3842f292019-08-23 16:57:54 +0100335 Py_ssize_t len = list->length;
336 if (len == PY_SSIZE_T_MAX) {
Min ho Kim96e12d52019-07-22 06:12:33 +1000337 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200338 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100339 }
Victor Stinner3842f292019-08-23 16:57:54 +0100340 if (index < 0) {
341 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
342 }
343 if (index > len) {
344 index = len;
345 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100346
Victor Stinner74f65682019-03-15 15:08:05 +0100347 wchar_t *item2 = _PyMem_RawWcsdup(item);
348 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200349 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100350 }
Victor Stinner74f65682019-03-15 15:08:05 +0100351
Victor Stinner3842f292019-08-23 16:57:54 +0100352 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100353 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
354 if (items2 == NULL) {
355 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200356 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100357 }
358
Victor Stinner3842f292019-08-23 16:57:54 +0100359 if (index < len) {
360 memmove(&items2[index + 1],
361 &items2[index],
362 (len - index) * sizeof(items2[0]));
363 }
364
365 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100366 list->items = items2;
367 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200368 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100369}
370
371
Victor Stinner331a6a52019-05-27 16:39:22 +0200372PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100373PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
374{
375 return PyWideStringList_Insert(list, list->length, item);
376}
377
378
379PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200380_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100381{
382 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200383 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
384 if (_PyStatus_EXCEPTION(status)) {
385 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100386 }
387 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200388 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100389}
390
391
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100392static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200393_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100394{
395 for (Py_ssize_t i = 0; i < list->length; i++) {
396 if (wcscmp(list->items[i], item) == 0) {
397 return 1;
398 }
399 }
400 return 0;
401}
402
403
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100404PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200405_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100406{
Victor Stinner331a6a52019-05-27 16:39:22 +0200407 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100408
Victor Stinner74f65682019-03-15 15:08:05 +0100409 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100410 if (pylist == NULL) {
411 return NULL;
412 }
413
Victor Stinner74f65682019-03-15 15:08:05 +0100414 for (Py_ssize_t i = 0; i < list->length; i++) {
415 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
416 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100417 Py_DECREF(pylist);
418 return NULL;
419 }
Victor Stinner74f65682019-03-15 15:08:05 +0100420 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100421 }
422 return pylist;
423}
424
425
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100426/* --- Py_SetStandardStreamEncoding() ----------------------------- */
427
Victor Stinner124b9eb2018-08-29 01:29:06 +0200428/* Helper to allow an embedding application to override the normal
429 * mechanism that attempts to figure out an appropriate IO encoding
430 */
431
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200432static char *_Py_StandardStreamEncoding = NULL;
433static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200434
435int
436Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
437{
438 if (Py_IsInitialized()) {
439 /* This is too late to have any effect */
440 return -1;
441 }
442
443 int res = 0;
444
445 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
446 but Py_Initialize() can change the allocator. Use a known allocator
447 to be able to release the memory later. */
448 PyMemAllocatorEx old_alloc;
449 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
450
451 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
452 * initialised yet.
453 *
454 * However, the raw memory allocators are initialised appropriately
455 * as C static variables, so _PyMem_RawStrdup is OK even though
456 * Py_Initialize hasn't been called yet.
457 */
458 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200459 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200460 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
461 if (!_Py_StandardStreamEncoding) {
462 res = -2;
463 goto done;
464 }
465 }
466 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200467 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200468 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
469 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200470 PyMem_RawFree(_Py_StandardStreamEncoding);
471 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200472 res = -3;
473 goto done;
474 }
475 }
476#ifdef MS_WINDOWS
477 if (_Py_StandardStreamEncoding) {
478 /* Overriding the stream encoding implies legacy streams */
479 Py_LegacyWindowsStdioFlag = 1;
480 }
481#endif
482
483done:
484 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
485
486 return res;
487}
488
489
490void
491_Py_ClearStandardStreamEncoding(void)
492{
493 /* Use the same allocator than Py_SetStandardStreamEncoding() */
494 PyMemAllocatorEx old_alloc;
495 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
496
497 /* We won't need them anymore. */
498 if (_Py_StandardStreamEncoding) {
499 PyMem_RawFree(_Py_StandardStreamEncoding);
500 _Py_StandardStreamEncoding = NULL;
501 }
502 if (_Py_StandardStreamErrors) {
503 PyMem_RawFree(_Py_StandardStreamErrors);
504 _Py_StandardStreamErrors = NULL;
505 }
506
507 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
508}
509
510
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100511/* --- Py_GetArgcArgv() ------------------------------------------- */
512
513/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200514static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100515
516
517void
518_Py_ClearArgcArgv(void)
519{
520 PyMemAllocatorEx old_alloc;
521 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
522
Victor Stinner331a6a52019-05-27 16:39:22 +0200523 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100524
525 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
526}
527
528
Victor Stinner4fffd382019-03-06 01:44:31 +0100529static int
Victor Stinner74f65682019-03-15 15:08:05 +0100530_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100531{
Victor Stinner331a6a52019-05-27 16:39:22 +0200532 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100533 int res;
534
535 PyMemAllocatorEx old_alloc;
536 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
537
Victor Stinner331a6a52019-05-27 16:39:22 +0200538 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100539
540 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
541 return res;
542}
543
544
545/* Make the *original* argc/argv available to other modules.
546 This is rare, but it is needed by the secureware extension. */
547void
548Py_GetArgcArgv(int *argc, wchar_t ***argv)
549{
Victor Stinner74f65682019-03-15 15:08:05 +0100550 *argc = (int)orig_argv.length;
551 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100552}
553
554
Victor Stinner331a6a52019-05-27 16:39:22 +0200555/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100556
557#define DECODE_LOCALE_ERR(NAME, LEN) \
558 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200559 ? _PyStatus_ERR("cannot decode " NAME) \
560 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100561
Victor Stinner441b10c2019-09-28 04:28:35 +0200562
Victor Stinner6c785c02018-08-01 17:56:14 +0200563/* Free memory allocated in config, but don't clear all attributes */
564void
Victor Stinner331a6a52019-05-27 16:39:22 +0200565PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200566{
567#define CLEAR(ATTR) \
568 do { \
569 PyMem_RawFree(ATTR); \
570 ATTR = NULL; \
571 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200572
573 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200574 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200575 CLEAR(config->home);
576 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200577
Victor Stinner331a6a52019-05-27 16:39:22 +0200578 _PyWideStringList_Clear(&config->argv);
579 _PyWideStringList_Clear(&config->warnoptions);
580 _PyWideStringList_Clear(&config->xoptions);
581 _PyWideStringList_Clear(&config->module_search_paths);
582 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200583
584 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700585 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200586 CLEAR(config->prefix);
587 CLEAR(config->base_prefix);
588 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200589 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200590
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200591 CLEAR(config->filesystem_encoding);
592 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200593 CLEAR(config->stdio_encoding);
594 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100595 CLEAR(config->run_command);
596 CLEAR(config->run_module);
597 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400598 CLEAR(config->check_hash_pycs_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200599#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200600}
601
602
Victor Stinner8462a492019-10-01 12:06:16 +0200603void
Victor Stinner331a6a52019-05-27 16:39:22 +0200604_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200605{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200606 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200607
Victor Stinner022be022019-05-22 23:58:50 +0200608 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200609 config->isolated = -1;
610 config->use_environment = -1;
611 config->dev_mode = -1;
612 config->install_signal_handlers = 1;
613 config->use_hash_seed = -1;
614 config->faulthandler = -1;
615 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200616 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200617 config->parse_argv = 0;
618 config->site_import = -1;
619 config->bytes_warning = -1;
620 config->inspect = -1;
621 config->interactive = -1;
622 config->optimization_level = -1;
623 config->parser_debug= -1;
624 config->write_bytecode = -1;
625 config->verbose = -1;
626 config->quiet = -1;
627 config->user_site_directory = -1;
628 config->configure_c_stdio = 0;
629 config->buffered_stdio = -1;
630 config->_install_importlib = 1;
631 config->check_hash_pycs_mode = NULL;
632 config->pathconfig_warnings = -1;
633 config->_init_main = 1;
634#ifdef MS_WINDOWS
635 config->legacy_windows_stdio = -1;
636#endif
637}
638
639
Victor Stinner8462a492019-10-01 12:06:16 +0200640static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200641config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200642{
Victor Stinner8462a492019-10-01 12:06:16 +0200643 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200644
645 config->isolated = 0;
646 config->use_environment = 1;
647 config->site_import = 1;
648 config->bytes_warning = 0;
649 config->inspect = 0;
650 config->interactive = 0;
651 config->optimization_level = 0;
652 config->parser_debug= 0;
653 config->write_bytecode = 1;
654 config->verbose = 0;
655 config->quiet = 0;
656 config->user_site_directory = 1;
657 config->buffered_stdio = 1;
658 config->pathconfig_warnings = 1;
659#ifdef MS_WINDOWS
660 config->legacy_windows_stdio = 0;
661#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200662}
663
664
Victor Stinner8462a492019-10-01 12:06:16 +0200665void
Victor Stinner331a6a52019-05-27 16:39:22 +0200666PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200667{
Victor Stinner8462a492019-10-01 12:06:16 +0200668 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200669
Victor Stinner022be022019-05-22 23:58:50 +0200670 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200671 config->configure_c_stdio = 1;
672 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200673}
674
675
Victor Stinner8462a492019-10-01 12:06:16 +0200676void
Victor Stinner331a6a52019-05-27 16:39:22 +0200677PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200678{
Victor Stinner8462a492019-10-01 12:06:16 +0200679 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200680
Victor Stinner022be022019-05-22 23:58:50 +0200681 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200682 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200683 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200684 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200685 config->dev_mode = 0;
686 config->install_signal_handlers = 0;
687 config->use_hash_seed = 0;
688 config->faulthandler = 0;
689 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200690 config->pathconfig_warnings = 0;
691#ifdef MS_WINDOWS
692 config->legacy_windows_stdio = 0;
693#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200694}
695
696
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200697/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200698PyStatus
699PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200700{
Victor Stinner331a6a52019-05-27 16:39:22 +0200701 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
702 if (_PyStatus_EXCEPTION(status)) {
703 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200704 }
705
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200706 wchar_t *str2;
707 if (str != NULL) {
708 str2 = _PyMem_RawWcsdup(str);
709 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200710 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200711 }
712 }
713 else {
714 str2 = NULL;
715 }
716 PyMem_RawFree(*config_str);
717 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200718 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200719}
720
721
Victor Stinner331a6a52019-05-27 16:39:22 +0200722static PyStatus
723config_set_bytes_string(PyConfig *config, wchar_t **config_str,
724 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200725{
Victor Stinner331a6a52019-05-27 16:39:22 +0200726 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
727 if (_PyStatus_EXCEPTION(status)) {
728 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400729 }
730
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200731 wchar_t *str2;
732 if (str != NULL) {
733 size_t len;
734 str2 = Py_DecodeLocale(str, &len);
735 if (str2 == NULL) {
736 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200737 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200738 }
739 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200740 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200741 }
742 }
743 }
744 else {
745 str2 = NULL;
746 }
747 PyMem_RawFree(*config_str);
748 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200749 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200750}
751
752
Victor Stinner331a6a52019-05-27 16:39:22 +0200753#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
754 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400755
756
Victor Stinner70005ac2019-05-02 15:25:34 -0400757/* Decode str using Py_DecodeLocale() and set the result into *config_str.
758 Pre-initialize Python if needed to ensure that encodings are properly
759 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200760PyStatus
761PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200762 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400763{
Victor Stinner331a6a52019-05-27 16:39:22 +0200764 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400765}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200766
767
Victor Stinner331a6a52019-05-27 16:39:22 +0200768PyStatus
769_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200770{
Victor Stinner331a6a52019-05-27 16:39:22 +0200771 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200772
Victor Stinner331a6a52019-05-27 16:39:22 +0200773 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200774
775#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200776#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200777 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200778 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
779 if (_PyStatus_EXCEPTION(status)) { \
780 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200781 } \
782 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100783#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200784 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200785 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200786 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200787 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200788 } while (0)
789
Victor Stinner6d1c4672019-05-20 11:02:00 +0200790 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100791 COPY_ATTR(isolated);
792 COPY_ATTR(use_environment);
793 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200794 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200795 COPY_ATTR(use_hash_seed);
796 COPY_ATTR(hash_seed);
797 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200798 COPY_ATTR(faulthandler);
799 COPY_ATTR(tracemalloc);
800 COPY_ATTR(import_time);
801 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200802 COPY_ATTR(dump_refs);
803 COPY_ATTR(malloc_stats);
804
Victor Stinner124b9eb2018-08-29 01:29:06 +0200805 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200806 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200807 COPY_WSTR_ATTR(home);
808 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200809
Victor Stinnerae239f62019-05-16 17:02:56 +0200810 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100811 COPY_WSTRLIST(argv);
812 COPY_WSTRLIST(warnoptions);
813 COPY_WSTRLIST(xoptions);
814 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200815 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200816
Victor Stinner124b9eb2018-08-29 01:29:06 +0200817 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700818 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200819 COPY_WSTR_ATTR(prefix);
820 COPY_WSTR_ATTR(base_prefix);
821 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200822 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200823
Victor Stinner6c785c02018-08-01 17:56:14 +0200824 COPY_ATTR(site_import);
825 COPY_ATTR(bytes_warning);
826 COPY_ATTR(inspect);
827 COPY_ATTR(interactive);
828 COPY_ATTR(optimization_level);
829 COPY_ATTR(parser_debug);
830 COPY_ATTR(write_bytecode);
831 COPY_ATTR(verbose);
832 COPY_ATTR(quiet);
833 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200834 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200835 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400836 COPY_WSTR_ATTR(filesystem_encoding);
837 COPY_WSTR_ATTR(filesystem_errors);
838 COPY_WSTR_ATTR(stdio_encoding);
839 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200840#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200841 COPY_ATTR(legacy_windows_stdio);
842#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100843 COPY_ATTR(skip_source_first_line);
844 COPY_WSTR_ATTR(run_command);
845 COPY_WSTR_ATTR(run_module);
846 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400847 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200848 COPY_ATTR(pathconfig_warnings);
849 COPY_ATTR(_init_main);
Victor Stinner6c785c02018-08-01 17:56:14 +0200850
851#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200852#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200853#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200854 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200855}
856
857
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100858static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200859config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100860{
861 PyObject *dict;
862
863 dict = PyDict_New();
864 if (dict == NULL) {
865 return NULL;
866 }
867
868#define SET_ITEM(KEY, EXPR) \
869 do { \
870 PyObject *obj = (EXPR); \
871 if (obj == NULL) { \
872 goto fail; \
873 } \
874 int res = PyDict_SetItemString(dict, (KEY), obj); \
875 Py_DECREF(obj); \
876 if (res < 0) { \
877 goto fail; \
878 } \
879 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100880#define SET_ITEM_INT(ATTR) \
881 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
882#define SET_ITEM_UINT(ATTR) \
883 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100884#define FROM_WSTRING(STR) \
885 ((STR != NULL) ? \
886 PyUnicode_FromWideChar(STR, -1) \
887 : (Py_INCREF(Py_None), Py_None))
888#define SET_ITEM_WSTR(ATTR) \
889 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
890#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200891 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100892
Victor Stinner6d1c4672019-05-20 11:02:00 +0200893 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100894 SET_ITEM_INT(isolated);
895 SET_ITEM_INT(use_environment);
896 SET_ITEM_INT(dev_mode);
897 SET_ITEM_INT(install_signal_handlers);
898 SET_ITEM_INT(use_hash_seed);
899 SET_ITEM_UINT(hash_seed);
900 SET_ITEM_INT(faulthandler);
901 SET_ITEM_INT(tracemalloc);
902 SET_ITEM_INT(import_time);
903 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100904 SET_ITEM_INT(dump_refs);
905 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400906 SET_ITEM_WSTR(filesystem_encoding);
907 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100908 SET_ITEM_WSTR(pycache_prefix);
909 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200910 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100911 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100912 SET_ITEM_WSTRLIST(xoptions);
913 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200914 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100915 SET_ITEM_WSTR(home);
916 SET_ITEM_WSTRLIST(module_search_paths);
917 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700918 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100919 SET_ITEM_WSTR(prefix);
920 SET_ITEM_WSTR(base_prefix);
921 SET_ITEM_WSTR(exec_prefix);
922 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100923 SET_ITEM_INT(site_import);
924 SET_ITEM_INT(bytes_warning);
925 SET_ITEM_INT(inspect);
926 SET_ITEM_INT(interactive);
927 SET_ITEM_INT(optimization_level);
928 SET_ITEM_INT(parser_debug);
929 SET_ITEM_INT(write_bytecode);
930 SET_ITEM_INT(verbose);
931 SET_ITEM_INT(quiet);
932 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200933 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100934 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400935 SET_ITEM_WSTR(stdio_encoding);
936 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100937#ifdef MS_WINDOWS
938 SET_ITEM_INT(legacy_windows_stdio);
939#endif
940 SET_ITEM_INT(skip_source_first_line);
941 SET_ITEM_WSTR(run_command);
942 SET_ITEM_WSTR(run_module);
943 SET_ITEM_WSTR(run_filename);
944 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400945 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200946 SET_ITEM_INT(pathconfig_warnings);
947 SET_ITEM_INT(_init_main);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100948
949 return dict;
950
951fail:
952 Py_DECREF(dict);
953 return NULL;
954
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100955#undef FROM_WSTRING
956#undef SET_ITEM
957#undef SET_ITEM_INT
958#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100959#undef SET_ITEM_WSTR
960#undef SET_ITEM_WSTRLIST
961}
962
963
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100964static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200965config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200966{
Victor Stinner20004952019-03-26 02:31:11 +0100967 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200968}
969
970
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100971/* Get a copy of the environment variable as wchar_t*.
972 Return 0 on success, but *dest can be NULL.
973 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200974static PyStatus
975config_get_env_dup(PyConfig *config,
976 wchar_t **dest,
977 wchar_t *wname, char *name,
978 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200979{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200980 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100981 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200982
Victor Stinner20004952019-03-26 02:31:11 +0100983 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200984 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200985 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200986 }
987
988#ifdef MS_WINDOWS
989 const wchar_t *var = _wgetenv(wname);
990 if (!var || var[0] == '\0') {
991 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200992 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200993 }
994
Victor Stinner331a6a52019-05-27 16:39:22 +0200995 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +0200996#else
997 const char *var = getenv(name);
998 if (!var || var[0] == '\0') {
999 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001000 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001001 }
1002
Victor Stinner331a6a52019-05-27 16:39:22 +02001003 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001004#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001005}
1006
1007
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001008#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001009 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001010
1011
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001012static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001013config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001014{
Victor Stinner022be022019-05-22 23:58:50 +02001015 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1016 /* Python and Isolated configuration ignore global variables */
1017 return;
1018 }
1019
Victor Stinner6c785c02018-08-01 17:56:14 +02001020#define COPY_FLAG(ATTR, VALUE) \
1021 if (config->ATTR == -1) { \
1022 config->ATTR = VALUE; \
1023 }
1024#define COPY_NOT_FLAG(ATTR, VALUE) \
1025 if (config->ATTR == -1) { \
1026 config->ATTR = !(VALUE); \
1027 }
1028
Victor Stinner20004952019-03-26 02:31:11 +01001029 COPY_FLAG(isolated, Py_IsolatedFlag);
1030 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001031 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1032 COPY_FLAG(inspect, Py_InspectFlag);
1033 COPY_FLAG(interactive, Py_InteractiveFlag);
1034 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1035 COPY_FLAG(parser_debug, Py_DebugFlag);
1036 COPY_FLAG(verbose, Py_VerboseFlag);
1037 COPY_FLAG(quiet, Py_QuietFlag);
1038#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001039 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1040#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001041 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001042
Victor Stinner6c785c02018-08-01 17:56:14 +02001043 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1044 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1045 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1046 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1047
Victor Stinner6c785c02018-08-01 17:56:14 +02001048#undef COPY_FLAG
1049#undef COPY_NOT_FLAG
1050}
1051
1052
1053/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001054static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001055config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001056{
1057#define COPY_FLAG(ATTR, VAR) \
1058 if (config->ATTR != -1) { \
1059 VAR = config->ATTR; \
1060 }
1061#define COPY_NOT_FLAG(ATTR, VAR) \
1062 if (config->ATTR != -1) { \
1063 VAR = !config->ATTR; \
1064 }
1065
Victor Stinner20004952019-03-26 02:31:11 +01001066 COPY_FLAG(isolated, Py_IsolatedFlag);
1067 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001068 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1069 COPY_FLAG(inspect, Py_InspectFlag);
1070 COPY_FLAG(interactive, Py_InteractiveFlag);
1071 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1072 COPY_FLAG(parser_debug, Py_DebugFlag);
1073 COPY_FLAG(verbose, Py_VerboseFlag);
1074 COPY_FLAG(quiet, Py_QuietFlag);
1075#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001076 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1077#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001078 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001079
Victor Stinner6c785c02018-08-01 17:56:14 +02001080 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1081 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1082 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1083 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1084
Victor Stinner6c785c02018-08-01 17:56:14 +02001085 /* Random or non-zero hash seed */
1086 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1087 config->hash_seed != 0);
1088
1089#undef COPY_FLAG
1090#undef COPY_NOT_FLAG
1091}
1092
1093
1094/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1095 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001096static PyStatus
1097config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001098{
Victor Stinner331a6a52019-05-27 16:39:22 +02001099 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001100
Victor Stinner6c785c02018-08-01 17:56:14 +02001101 /* If Py_SetProgramName() was called, use its value */
1102 const wchar_t *program_name = _Py_path_config.program_name;
1103 if (program_name != NULL) {
1104 config->program_name = _PyMem_RawWcsdup(program_name);
1105 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001106 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001107 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001108 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001109 }
1110
1111#ifdef __APPLE__
1112 /* On MacOS X, when the Python interpreter is embedded in an
1113 application bundle, it gets executed by a bootstrapping script
1114 that does os.execve() with an argv[0] that's different from the
1115 actual Python executable. This is needed to keep the Finder happy,
1116 or rather, to work around Apple's overly strict requirements of
1117 the process name. However, we still need a usable sys.executable,
1118 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001119 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001120 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001121 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001122 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001123 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1124 "PYTHONEXECUTABLE environment variable");
1125 if (_PyStatus_EXCEPTION(status)) {
1126 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001127 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001128 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001129 }
1130#ifdef WITH_NEXT_FRAMEWORK
1131 else {
1132 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1133 if (pyvenv_launcher && *pyvenv_launcher) {
1134 /* Used by Mac/Tools/pythonw.c to forward
1135 * the argv0 of the stub executable
1136 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001137 status = CONFIG_SET_BYTES_STR(config,
1138 &config->program_name,
1139 pyvenv_launcher,
1140 "__PYVENV_LAUNCHER__ environment variable");
1141 if (_PyStatus_EXCEPTION(status)) {
1142 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001143 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001144
1145 /*
1146 * This environment variable is used to communicate between
1147 * the stub launcher and the real interpreter and isn't needed
1148 * beyond this point.
1149 *
1150 * Clean up to avoid problems when launching other programs
1151 * later on.
1152 */
1153 (void)unsetenv("__PYVENV_LAUNCHER__");
1154
Victor Stinner331a6a52019-05-27 16:39:22 +02001155 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001156 }
1157 }
1158#endif /* WITH_NEXT_FRAMEWORK */
1159#endif /* __APPLE__ */
1160
Victor Stinnerfed02e12019-05-17 11:12:09 +02001161 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001162 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001163 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1164 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1165 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001166 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001167 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001168 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001169 }
1170
Victor Stinnerfed02e12019-05-17 11:12:09 +02001171 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001172#ifdef MS_WINDOWS
1173 const wchar_t *default_program_name = L"python";
1174#else
1175 const wchar_t *default_program_name = L"python3";
1176#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001177 status = PyConfig_SetString(config, &config->program_name,
1178 default_program_name);
1179 if (_PyStatus_EXCEPTION(status)) {
1180 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001181 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001182 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001183}
1184
Victor Stinner331a6a52019-05-27 16:39:22 +02001185static PyStatus
1186config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001187{
1188 assert(config->executable == NULL);
1189
1190 /* If Py_SetProgramFullPath() was called, use its value */
1191 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1192 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001193 PyStatus status = PyConfig_SetString(config,
1194 &config->executable,
1195 program_full_path);
1196 if (_PyStatus_EXCEPTION(status)) {
1197 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001198 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001199 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001200 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001201 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001202}
Victor Stinner6c785c02018-08-01 17:56:14 +02001203
Victor Stinner4fffd382019-03-06 01:44:31 +01001204
Victor Stinner6c785c02018-08-01 17:56:14 +02001205static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001206config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001207{
Victor Stinner74f65682019-03-15 15:08:05 +01001208 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001209}
1210
1211
Victor Stinner331a6a52019-05-27 16:39:22 +02001212static PyStatus
1213config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001214{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001215 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001216
1217 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001218 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001219 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001220 PyStatus status = PyConfig_SetString(config, &config->home, home);
1221 if (_PyStatus_EXCEPTION(status)) {
1222 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001223 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001224 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001225 }
1226
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001227 return CONFIG_GET_ENV_DUP(config, &config->home,
1228 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001229}
1230
1231
Victor Stinner331a6a52019-05-27 16:39:22 +02001232static PyStatus
1233config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001234{
Victor Stinner331a6a52019-05-27 16:39:22 +02001235 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001236
1237 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1238 /* Convert a text seed to a numeric one */
1239 if (seed_text && strcmp(seed_text, "random") != 0) {
1240 const char *endptr = seed_text;
1241 unsigned long seed;
1242 errno = 0;
1243 seed = strtoul(seed_text, (char **)&endptr, 10);
1244 if (*endptr != '\0'
1245 || seed > 4294967295UL
1246 || (errno == ERANGE && seed == ULONG_MAX))
1247 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001248 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001249 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001250 }
1251 /* Use a specific hash */
1252 config->use_hash_seed = 1;
1253 config->hash_seed = seed;
1254 }
1255 else {
1256 /* Use a random hash */
1257 config->use_hash_seed = 0;
1258 config->hash_seed = 0;
1259 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001260 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001261}
1262
1263
Victor Stinner6c785c02018-08-01 17:56:14 +02001264static int
1265config_wstr_to_int(const wchar_t *wstr, int *result)
1266{
1267 const wchar_t *endptr = wstr;
1268 errno = 0;
1269 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1270 if (*endptr != '\0' || errno == ERANGE) {
1271 return -1;
1272 }
1273 if (value < INT_MIN || value > INT_MAX) {
1274 return -1;
1275 }
1276
1277 *result = (int)value;
1278 return 0;
1279}
1280
1281
Victor Stinner331a6a52019-05-27 16:39:22 +02001282static PyStatus
1283config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001284{
Victor Stinner331a6a52019-05-27 16:39:22 +02001285 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001286 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001287
Victor Stinner6c785c02018-08-01 17:56:14 +02001288 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001289 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1290 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1291 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1292 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001293
1294 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001295 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001296 if (dont_write_bytecode) {
1297 config->write_bytecode = 0;
1298 }
1299
1300 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001301 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001302 if (no_user_site_directory) {
1303 config->user_site_directory = 0;
1304 }
1305
1306 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001307 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001308 if (unbuffered_stdio) {
1309 config->buffered_stdio = 0;
1310 }
1311
1312#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001313 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001314 "PYTHONLEGACYWINDOWSSTDIO");
1315#endif
1316
Victor Stinner331a6a52019-05-27 16:39:22 +02001317 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001318 config->dump_refs = 1;
1319 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001320 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001321 config->malloc_stats = 1;
1322 }
1323
Victor Stinner331a6a52019-05-27 16:39:22 +02001324 if (config->pythonpath_env == NULL) {
1325 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1326 L"PYTHONPATH", "PYTHONPATH");
1327 if (_PyStatus_EXCEPTION(status)) {
1328 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001329 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001330 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001331
1332 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001333 status = config_init_hash_seed(config);
1334 if (_PyStatus_EXCEPTION(status)) {
1335 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001336 }
1337 }
1338
Victor Stinner331a6a52019-05-27 16:39:22 +02001339 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001340}
1341
1342
Victor Stinner331a6a52019-05-27 16:39:22 +02001343static PyStatus
1344config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001345{
1346 int nframe;
1347 int valid;
1348
Victor Stinner331a6a52019-05-27 16:39:22 +02001349 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001350 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001351 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001352 valid = (nframe >= 0);
1353 }
1354 else {
1355 valid = 0;
1356 }
1357 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001358 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001359 }
1360 config->tracemalloc = nframe;
1361 }
1362
1363 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1364 if (xoption) {
1365 const wchar_t *sep = wcschr(xoption, L'=');
1366 if (sep) {
1367 if (!config_wstr_to_int(sep + 1, &nframe)) {
1368 valid = (nframe >= 0);
1369 }
1370 else {
1371 valid = 0;
1372 }
1373 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001374 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1375 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001376 }
1377 }
1378 else {
1379 /* -X tracemalloc behaves as -X tracemalloc=1 */
1380 nframe = 1;
1381 }
1382 config->tracemalloc = nframe;
1383 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001384 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001385}
1386
1387
Victor Stinner331a6a52019-05-27 16:39:22 +02001388static PyStatus
1389config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001390{
1391 assert(config->pycache_prefix == NULL);
1392
1393 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1394 if (xoption) {
1395 const wchar_t *sep = wcschr(xoption, L'=');
1396 if (sep && wcslen(sep) > 1) {
1397 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1398 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001399 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001400 }
1401 }
1402 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001403 // PYTHONPYCACHEPREFIX env var ignored
1404 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001405 config->pycache_prefix = NULL;
1406 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001407 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001408 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001409
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001410 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1411 L"PYTHONPYCACHEPREFIX",
1412 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001413}
1414
1415
Victor Stinner331a6a52019-05-27 16:39:22 +02001416static PyStatus
1417config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001418{
1419 /* More complex options configured by env var and -X option */
1420 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001421 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001422 || config_get_xoption(config, L"faulthandler")) {
1423 config->faulthandler = 1;
1424 }
1425 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001426 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001427 || config_get_xoption(config, L"importtime")) {
1428 config->import_time = 1;
1429 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001430
Victor Stinner331a6a52019-05-27 16:39:22 +02001431 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001432 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001433 status = config_init_tracemalloc(config);
1434 if (_PyStatus_EXCEPTION(status)) {
1435 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001436 }
1437 }
1438
1439 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001440 status = config_init_pycache_prefix(config);
1441 if (_PyStatus_EXCEPTION(status)) {
1442 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001443 }
1444 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001445 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001446}
1447
1448
Victor Stinner709d23d2019-05-02 14:56:30 -04001449static const wchar_t *
Andy Lesteraa450a02020-03-07 11:36:04 -06001450config_get_stdio_errors(void)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001451{
1452#ifndef MS_WINDOWS
1453 const char *loc = setlocale(LC_CTYPE, NULL);
1454 if (loc != NULL) {
1455 /* surrogateescape is the default in the legacy C and POSIX locales */
1456 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001457 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001458 }
1459
1460#ifdef PY_COERCE_C_LOCALE
1461 /* surrogateescape is the default in locale coercion target locales */
1462 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001463 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001464 }
1465#endif
1466 }
1467
Victor Stinner709d23d2019-05-02 14:56:30 -04001468 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001469#else
1470 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001471 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001472#endif
1473}
1474
1475
Victor Stinner331a6a52019-05-27 16:39:22 +02001476static PyStatus
1477config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001478{
1479#ifdef MS_WINDOWS
1480 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001481 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001482 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001483#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001484 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001485#else
1486 const char *encoding = nl_langinfo(CODESET);
1487 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001488 return _PyStatus_ERR("failed to get the locale encoding: "
1489 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001490 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001491 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001492 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001493 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001494 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001495#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001496}
1497
1498
Victor Stinner331a6a52019-05-27 16:39:22 +02001499static PyStatus
1500config_init_stdio_encoding(PyConfig *config,
1501 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001502{
Victor Stinner331a6a52019-05-27 16:39:22 +02001503 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001504
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001505 /* If Py_SetStandardStreamEncoding() have been called, use these
1506 parameters. */
1507 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001508 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1509 _Py_StandardStreamEncoding,
1510 "_Py_StandardStreamEncoding");
1511 if (_PyStatus_EXCEPTION(status)) {
1512 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001513 }
1514 }
1515
1516 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001517 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1518 _Py_StandardStreamErrors,
1519 "_Py_StandardStreamErrors");
1520 if (_PyStatus_EXCEPTION(status)) {
1521 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001522 }
1523 }
1524
1525 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001526 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001527 }
1528
1529 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001530 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001531 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001532 char *pythonioencoding = _PyMem_RawStrdup(opt);
1533 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001534 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001535 }
1536
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001537 char *errors = strchr(pythonioencoding, ':');
1538 if (errors) {
1539 *errors = '\0';
1540 errors++;
1541 if (!errors[0]) {
1542 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001543 }
1544 }
1545
1546 /* Does PYTHONIOENCODING contain an encoding? */
1547 if (pythonioencoding[0]) {
1548 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001549 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1550 pythonioencoding,
1551 "PYTHONIOENCODING environment variable");
1552 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001553 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001554 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001555 }
1556 }
1557
1558 /* If the encoding is set but not the error handler,
1559 use "strict" error handler by default.
1560 PYTHONIOENCODING=latin1 behaves as
1561 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001562 if (!errors) {
1563 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001564 }
1565 }
1566
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001567 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001568 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1569 errors,
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 PyMem_RawFree(pythonioencoding);
1578 }
1579
1580 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001581 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001582 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001583 status = PyConfig_SetString(config, &config->stdio_encoding,
1584 L"utf-8");
1585 if (_PyStatus_EXCEPTION(status)) {
1586 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001587 }
1588 }
1589 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001590 status = PyConfig_SetString(config, &config->stdio_errors,
1591 L"surrogateescape");
1592 if (_PyStatus_EXCEPTION(status)) {
1593 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001594 }
1595 }
1596 }
1597
1598 /* Choose the default error handler based on the current locale. */
1599 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001600 status = config_get_locale_encoding(config, &config->stdio_encoding);
1601 if (_PyStatus_EXCEPTION(status)) {
1602 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001603 }
1604 }
1605 if (config->stdio_errors == NULL) {
Andy Lesteraa450a02020-03-07 11:36:04 -06001606 const wchar_t *errors = config_get_stdio_errors();
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001607 assert(errors != NULL);
1608
Victor Stinner331a6a52019-05-27 16:39:22 +02001609 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1610 if (_PyStatus_EXCEPTION(status)) {
1611 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001612 }
1613 }
1614
Victor Stinner331a6a52019-05-27 16:39:22 +02001615 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001616}
1617
1618
Victor Stinner331a6a52019-05-27 16:39:22 +02001619static PyStatus
1620config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001621{
Victor Stinner331a6a52019-05-27 16:39:22 +02001622 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001623
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001624 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001625#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001626 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001627#else
Victor Stinnere2510952019-05-02 11:28:57 -04001628
1629#ifdef MS_WINDOWS
1630 if (preconfig->legacy_windows_fs_encoding) {
1631 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001632 status = PyConfig_SetString(config, &config->filesystem_encoding,
1633 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001634 }
1635 else
1636#endif
Victor Stinner20004952019-03-26 02:31:11 +01001637 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001638 status = PyConfig_SetString(config, &config->filesystem_encoding,
1639 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001640 }
Victor Stinnere2510952019-05-02 11:28:57 -04001641#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001642 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001643 status = PyConfig_SetString(config, &config->filesystem_encoding,
1644 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001645 }
Victor Stinnere2510952019-05-02 11:28:57 -04001646#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001647 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001648#ifdef MS_WINDOWS
1649 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001650 status = PyConfig_SetString(config, &config->filesystem_encoding,
1651 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001652#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001653 status = config_get_locale_encoding(config,
1654 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001655#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001656 }
Victor Stinnere2510952019-05-02 11:28:57 -04001657#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001658
Victor Stinner331a6a52019-05-27 16:39:22 +02001659 if (_PyStatus_EXCEPTION(status)) {
1660 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001661 }
1662 }
1663
1664 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001665 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001666#ifdef MS_WINDOWS
1667 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001668 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001669 }
1670 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001671 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001672 }
1673#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001674 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001675#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001676 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1677 if (_PyStatus_EXCEPTION(status)) {
1678 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001679 }
1680 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001681 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001682}
1683
1684
Victor Stinner331a6a52019-05-27 16:39:22 +02001685static PyStatus
1686config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001687{
Victor Stinner331a6a52019-05-27 16:39:22 +02001688 PyStatus status;
1689 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001690
Victor Stinner20004952019-03-26 02:31:11 +01001691 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001692 status = config_read_env_vars(config);
1693 if (_PyStatus_EXCEPTION(status)) {
1694 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001695 }
1696 }
1697
1698 /* -X options */
1699 if (config_get_xoption(config, L"showrefcount")) {
1700 config->show_ref_count = 1;
1701 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001702
Victor Stinner331a6a52019-05-27 16:39:22 +02001703 status = config_read_complex_options(config);
1704 if (_PyStatus_EXCEPTION(status)) {
1705 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001706 }
1707
Victor Stinner6c785c02018-08-01 17:56:14 +02001708 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001709 status = config_init_home(config);
1710 if (_PyStatus_EXCEPTION(status)) {
1711 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001712 }
1713 }
1714
Steve Dower177a41a2018-11-17 20:41:48 -08001715 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001716 status = config_init_executable(config);
1717 if (_PyStatus_EXCEPTION(status)) {
1718 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001719 }
1720 }
1721
Victor Stinner6c785c02018-08-01 17:56:14 +02001722 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001723 status = _PyConfig_InitPathConfig(config);
1724 if (_PyStatus_EXCEPTION(status)) {
1725 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001726 }
1727 }
1728
1729 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001730 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001731 if (config->faulthandler < 0) {
1732 config->faulthandler = 1;
1733 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001734 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001735 if (config->faulthandler < 0) {
1736 config->faulthandler = 0;
1737 }
1738 if (config->tracemalloc < 0) {
1739 config->tracemalloc = 0;
1740 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001741 if (config->use_hash_seed < 0) {
1742 config->use_hash_seed = 0;
1743 config->hash_seed = 0;
1744 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001745
Victor Stinner70fead22018-08-29 13:45:34 +02001746 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001747 status = config_init_fs_encoding(config, preconfig);
1748 if (_PyStatus_EXCEPTION(status)) {
1749 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001750 }
1751 }
1752
Victor Stinner331a6a52019-05-27 16:39:22 +02001753 status = config_init_stdio_encoding(config, preconfig);
1754 if (_PyStatus_EXCEPTION(status)) {
1755 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001756 }
1757
Victor Stinner62599762019-03-15 16:03:23 +01001758 if (config->argv.length < 1) {
1759 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001760 status = PyWideStringList_Append(&config->argv, L"");
1761 if (_PyStatus_EXCEPTION(status)) {
1762 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001763 }
1764 }
Victor Stinner870b0352019-05-17 03:15:12 +02001765
1766 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001767 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1768 L"default");
1769 if (_PyStatus_EXCEPTION(status)) {
1770 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001771 }
1772 }
1773
1774 if (config->configure_c_stdio < 0) {
1775 config->configure_c_stdio = 1;
1776 }
1777
Victor Stinner331a6a52019-05-27 16:39:22 +02001778 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001779}
Victor Stinner5ed69952018-11-06 15:59:52 +01001780
1781
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001782static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001783config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001784{
1785#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1786 /* don't translate newlines (\r\n <=> \n) */
1787 _setmode(fileno(stdin), O_BINARY);
1788 _setmode(fileno(stdout), O_BINARY);
1789 _setmode(fileno(stderr), O_BINARY);
1790#endif
1791
1792 if (!config->buffered_stdio) {
1793#ifdef HAVE_SETVBUF
1794 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1795 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1796 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1797#else /* !HAVE_SETVBUF */
1798 setbuf(stdin, (char *)NULL);
1799 setbuf(stdout, (char *)NULL);
1800 setbuf(stderr, (char *)NULL);
1801#endif /* !HAVE_SETVBUF */
1802 }
1803 else if (config->interactive) {
1804#ifdef MS_WINDOWS
1805 /* Doesn't have to have line-buffered -- use unbuffered */
1806 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1807 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1808#else /* !MS_WINDOWS */
1809#ifdef HAVE_SETVBUF
1810 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1811 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1812#endif /* HAVE_SETVBUF */
1813#endif /* !MS_WINDOWS */
1814 /* Leave stderr alone - it should be unbuffered anyway. */
1815 }
1816}
1817
1818
1819/* Write the configuration:
1820
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001821 - set Py_xxx global configuration variables
1822 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001823void
Victor Stinner331a6a52019-05-27 16:39:22 +02001824_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001825{
Victor Stinner331a6a52019-05-27 16:39:22 +02001826 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001827
1828 if (config->configure_c_stdio) {
1829 config_init_stdio(config);
1830 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001831
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001832 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001833 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001834 preconfig->isolated = config->isolated;
1835 preconfig->use_environment = config->use_environment;
1836 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001837}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001838
1839
Victor Stinner331a6a52019-05-27 16:39:22 +02001840/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001841
1842static void
Victor Stinner2f549082019-03-29 15:13:46 +01001843config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001844{
Victor Stinner2f549082019-03-29 15:13:46 +01001845 FILE *f = error ? stderr : stdout;
1846
1847 fprintf(f, usage_line, program);
1848 if (error)
1849 fprintf(f, "Try `python -h' for more information.\n");
1850 else {
1851 fputs(usage_1, f);
1852 fputs(usage_2, f);
1853 fputs(usage_3, f);
1854 fprintf(f, usage_4, (wint_t)DELIM);
1855 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1856 fputs(usage_6, f);
1857 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001858}
1859
1860
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001861/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001862static PyStatus
1863config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001864 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001865{
Victor Stinner331a6a52019-05-27 16:39:22 +02001866 PyStatus status;
1867 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001868 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001869 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001870
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001871 _PyOS_ResetGetOpt();
1872 do {
1873 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001874 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001875 if (c == EOF) {
1876 break;
1877 }
1878
1879 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001880 if (config->run_command == NULL) {
1881 /* -c is the last option; following arguments
1882 that look like options are left for the
1883 command to interpret. */
1884 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1885 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1886 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001887 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001888 }
1889 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1890 command[len - 2] = '\n';
1891 command[len - 1] = 0;
1892 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001893 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001894 break;
1895 }
1896
1897 if (c == 'm') {
1898 /* -m is the last option; following arguments
1899 that look like options are left for the
1900 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001901 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001902 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1903 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001904 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001905 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001906 }
1907 break;
1908 }
1909
1910 switch (c) {
1911 case 0:
1912 // Handle long option.
1913 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001914 if (wcscmp(_PyOS_optarg, L"always") == 0
1915 || wcscmp(_PyOS_optarg, L"never") == 0
1916 || wcscmp(_PyOS_optarg, L"default") == 0)
1917 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001918 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1919 _PyOS_optarg);
1920 if (_PyStatus_EXCEPTION(status)) {
1921 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001922 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001923 } else {
1924 fprintf(stderr, "--check-hash-based-pycs must be one of "
1925 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001926 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001927 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001928 }
1929 break;
1930
1931 case 'b':
1932 config->bytes_warning++;
1933 break;
1934
1935 case 'd':
1936 config->parser_debug++;
1937 break;
1938
1939 case 'i':
1940 config->inspect++;
1941 config->interactive++;
1942 break;
1943
Victor Stinner6dcb5422019-03-05 02:44:12 +01001944 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001945 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001946 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001947 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001948 break;
1949
1950 /* case 'J': reserved for Jython */
1951
1952 case 'O':
1953 config->optimization_level++;
1954 break;
1955
1956 case 'B':
1957 config->write_bytecode = 0;
1958 break;
1959
1960 case 's':
1961 config->user_site_directory = 0;
1962 break;
1963
1964 case 'S':
1965 config->site_import = 0;
1966 break;
1967
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001968 case 't':
1969 /* ignored for backwards compatibility */
1970 break;
1971
1972 case 'u':
1973 config->buffered_stdio = 0;
1974 break;
1975
1976 case 'v':
1977 config->verbose++;
1978 break;
1979
1980 case 'x':
1981 config->skip_source_first_line = 1;
1982 break;
1983
1984 case 'h':
1985 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001986 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001987 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001988
1989 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01001990 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001991 break;
1992
1993 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02001994 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
1995 if (_PyStatus_EXCEPTION(status)) {
1996 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001997 }
1998 break;
1999
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002000 case 'q':
2001 config->quiet++;
2002 break;
2003
2004 case 'R':
2005 config->use_hash_seed = 0;
2006 break;
2007
2008 /* This space reserved for other options */
2009
2010 default:
2011 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002012 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002013 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002014 }
2015 } while (1);
2016
Victor Stinner2f549082019-03-29 15:13:46 +01002017 if (print_version) {
2018 printf("Python %s\n",
2019 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002020 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002021 }
2022
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002023 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002024 && _PyOS_optind < argv->length
2025 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002026 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002027 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002028 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002029 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002030 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002031 }
2032 }
2033
2034 if (config->run_command != NULL || config->run_module != NULL) {
2035 /* Backup _PyOS_optind */
2036 _PyOS_optind--;
2037 }
2038
Victor Stinnerae239f62019-05-16 17:02:56 +02002039 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002040
Victor Stinner331a6a52019-05-27 16:39:22 +02002041 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002042}
2043
2044
2045#ifdef MS_WINDOWS
2046# define WCSTOK wcstok_s
2047#else
2048# define WCSTOK wcstok
2049#endif
2050
2051/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002052static PyStatus
2053config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002054{
Victor Stinner331a6a52019-05-27 16:39:22 +02002055 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002056 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2057 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002058 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002059 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002060 if (_PyStatus_EXCEPTION(status)) {
2061 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002062 }
2063
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002064 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002065 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002066 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002067 }
2068
2069
2070 wchar_t *warning, *context = NULL;
2071 for (warning = WCSTOK(env, L",", &context);
2072 warning != NULL;
2073 warning = WCSTOK(NULL, L",", &context))
2074 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002075 status = PyWideStringList_Append(warnoptions, warning);
2076 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002077 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002078 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002079 }
2080 }
2081 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002082 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002083}
2084
2085
Victor Stinner331a6a52019-05-27 16:39:22 +02002086static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002087warnoptions_append(PyConfig *config, PyWideStringList *options,
2088 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002089{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002090 /* config_init_warnoptions() add existing config warnoptions at the end:
2091 ensure that the new option is not already present in this list to
2092 prevent change the options order whne config_init_warnoptions() is
2093 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002094 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002095 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002096 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002097 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002098 if (_PyWideStringList_Find(options, option)) {
2099 /* Already present: do nothing */
2100 return _PyStatus_OK();
2101 }
2102 return PyWideStringList_Append(options, option);
2103}
2104
2105
2106static PyStatus
2107warnoptions_extend(PyConfig *config, PyWideStringList *options,
2108 const PyWideStringList *options2)
2109{
2110 const Py_ssize_t len = options2->length;
2111 wchar_t *const *items = options2->items;
2112
2113 for (Py_ssize_t i = 0; i < len; i++) {
2114 PyStatus status = warnoptions_append(config, options, items[i]);
2115 if (_PyStatus_EXCEPTION(status)) {
2116 return status;
2117 }
2118 }
2119 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002120}
2121
2122
Victor Stinner331a6a52019-05-27 16:39:22 +02002123static PyStatus
2124config_init_warnoptions(PyConfig *config,
2125 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002126 const PyWideStringList *env_warnoptions,
2127 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002128{
Victor Stinner331a6a52019-05-27 16:39:22 +02002129 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002130 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002131
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002132 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002133 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002134 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002135 * - PyConfig.dev_mode: "default" filter
2136 * - PYTHONWARNINGS environment variable
2137 * - '-W' command line options
2138 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2139 * "default::BytesWarning" or "error::BytesWarning" filter
2140 * - early PySys_AddWarnOption() calls
2141 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002142 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002143 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2144 * module works on the basis of "the most recently added filter will be
2145 * checked first", we add the lowest precedence entries first so that later
2146 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002147 */
2148
Victor Stinner20004952019-03-26 02:31:11 +01002149 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002150 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002151 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002152 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002153 }
2154 }
2155
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002156 status = warnoptions_extend(config, &options, env_warnoptions);
2157 if (_PyStatus_EXCEPTION(status)) {
2158 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002159 }
2160
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002161 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2162 if (_PyStatus_EXCEPTION(status)) {
2163 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002164 }
2165
2166 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2167 * don't even try to emit a warning, so we skip setting the filter in that
2168 * case.
2169 */
2170 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002171 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002172 if (config->bytes_warning> 1) {
2173 filter = L"error::BytesWarning";
2174 }
2175 else {
2176 filter = L"default::BytesWarning";
2177 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002178 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002179 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002180 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002181 }
2182 }
Victor Stinner120b7072019-08-23 18:03:08 +01002183
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002184 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002185 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002186 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002187 }
2188
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002189 /* Always add all PyConfig.warnoptions options */
2190 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2191 if (_PyStatus_EXCEPTION(status)) {
2192 goto error;
2193 }
2194
2195 _PyWideStringList_Clear(&config->warnoptions);
2196 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002197 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002198
2199error:
2200 _PyWideStringList_Clear(&options);
2201 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002202}
2203
2204
Victor Stinner331a6a52019-05-27 16:39:22 +02002205static PyStatus
2206config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002207{
Victor Stinner331a6a52019-05-27 16:39:22 +02002208 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002209 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002210
Victor Stinner74f65682019-03-15 15:08:05 +01002211 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002212 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002213 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002214 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2215 if (_PyStatus_EXCEPTION(status)) {
2216 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002217 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002218 }
2219 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002220 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002221 slice.length = cmdline_argv->length - opt_index;
2222 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002223 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2224 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002225 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002226 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002227 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002228
2229 wchar_t *arg0 = NULL;
2230 if (config->run_command != NULL) {
2231 /* Force sys.argv[0] = '-c' */
2232 arg0 = L"-c";
2233 }
2234 else if (config->run_module != NULL) {
2235 /* Force sys.argv[0] = '-m'*/
2236 arg0 = L"-m";
2237 }
Victor Stinner3939c322019-06-25 15:02:43 +02002238
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002239 if (arg0 != NULL) {
2240 arg0 = _PyMem_RawWcsdup(arg0);
2241 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002242 _PyWideStringList_Clear(&config_argv);
2243 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002244 }
2245
Victor Stinnerfa153762019-03-20 04:25:38 +01002246 PyMem_RawFree(config_argv.items[0]);
2247 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002248 }
2249
Victor Stinner331a6a52019-05-27 16:39:22 +02002250 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002251 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002252 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002253}
2254
2255
Victor Stinner331a6a52019-05-27 16:39:22 +02002256static PyStatus
2257core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002258{
Victor Stinner331a6a52019-05-27 16:39:22 +02002259 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002260
Victor Stinnercab5d072019-05-17 19:01:14 +02002261 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002262 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2263 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002264 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002265 }
2266
Victor Stinner331a6a52019-05-27 16:39:22 +02002267 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002268
2269 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2270 if (_PyStatus_EXCEPTION(status)) {
2271 return status;
2272 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002273
Victor Stinner331a6a52019-05-27 16:39:22 +02002274 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002275
Victor Stinner331a6a52019-05-27 16:39:22 +02002276 status = _PyPreCmdline_Read(precmdline, &preconfig);
2277 if (_PyStatus_EXCEPTION(status)) {
2278 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002279 }
2280
Victor Stinner331a6a52019-05-27 16:39:22 +02002281 status = _PyPreCmdline_SetConfig(precmdline, config);
2282 if (_PyStatus_EXCEPTION(status)) {
2283 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002284 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002285 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002286}
2287
2288
Victor Stinner3939c322019-06-25 15:02:43 +02002289/* Get run_filename absolute path */
2290static PyStatus
2291config_run_filename_abspath(PyConfig *config)
2292{
2293 if (!config->run_filename) {
2294 return _PyStatus_OK();
2295 }
2296
2297#ifndef MS_WINDOWS
2298 if (_Py_isabs(config->run_filename)) {
2299 /* path is already absolute */
2300 return _PyStatus_OK();
2301 }
2302#endif
2303
2304 wchar_t *abs_filename;
2305 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2306 /* failed to get the absolute path of the command line filename:
2307 ignore the error, keep the relative path */
2308 return _PyStatus_OK();
2309 }
2310 if (abs_filename == NULL) {
2311 return _PyStatus_NO_MEMORY();
2312 }
2313
2314 PyMem_RawFree(config->run_filename);
2315 config->run_filename = abs_filename;
2316 return _PyStatus_OK();
2317}
2318
2319
Victor Stinner331a6a52019-05-27 16:39:22 +02002320static PyStatus
2321config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002322{
Victor Stinner331a6a52019-05-27 16:39:22 +02002323 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002324 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2325 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2326 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002327
Victor Stinnerae239f62019-05-16 17:02:56 +02002328 if (config->parse_argv < 0) {
2329 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002330 }
Victor Stinner870b0352019-05-17 03:15:12 +02002331
Victor Stinnerfed02e12019-05-17 11:12:09 +02002332 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002333 status = config_init_program_name(config);
2334 if (_PyStatus_EXCEPTION(status)) {
2335 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002336 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002337 }
Victor Stinner2f549082019-03-29 15:13:46 +01002338
Victor Stinnerae239f62019-05-16 17:02:56 +02002339 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002340 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002341 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2342 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002343 goto done;
2344 }
2345
Victor Stinner3939c322019-06-25 15:02:43 +02002346 status = config_run_filename_abspath(config);
2347 if (_PyStatus_EXCEPTION(status)) {
2348 goto done;
2349 }
2350
Victor Stinner331a6a52019-05-27 16:39:22 +02002351 status = config_update_argv(config, opt_index);
2352 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002353 goto done;
2354 }
Victor Stinner2f549082019-03-29 15:13:46 +01002355 }
Victor Stinner3939c322019-06-25 15:02:43 +02002356 else {
2357 status = config_run_filename_abspath(config);
2358 if (_PyStatus_EXCEPTION(status)) {
2359 goto done;
2360 }
2361 }
Victor Stinner2f549082019-03-29 15:13:46 +01002362
Victor Stinner2f549082019-03-29 15:13:46 +01002363 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002364 status = config_init_env_warnoptions(config, &env_warnoptions);
2365 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002366 goto done;
2367 }
2368 }
2369
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002370 /* Handle early PySys_AddWarnOption() calls */
2371 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2372 if (_PyStatus_EXCEPTION(status)) {
2373 goto done;
2374 }
2375
Victor Stinner331a6a52019-05-27 16:39:22 +02002376 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002377 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002378 &env_warnoptions,
2379 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002380 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002381 goto done;
2382 }
2383
Victor Stinner331a6a52019-05-27 16:39:22 +02002384 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002385
2386done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002387 _PyWideStringList_Clear(&cmdline_warnoptions);
2388 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002389 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002390 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002391}
2392
2393
Victor Stinner331a6a52019-05-27 16:39:22 +02002394PyStatus
2395_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002396{
Victor Stinner331a6a52019-05-27 16:39:22 +02002397 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2398 if (_PyStatus_EXCEPTION(status)) {
2399 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002400 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002401
Victor Stinner5f38b842019-05-01 02:30:12 +02002402 return _PyArgv_AsWstrList(args, &config->argv);
2403}
2404
2405
Victor Stinner70005ac2019-05-02 15:25:34 -04002406/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2407 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002408PyStatus
2409PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002410{
2411 _PyArgv args = {
2412 .argc = argc,
2413 .use_bytes_argv = 1,
2414 .bytes_argv = argv,
2415 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002416 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002417}
2418
2419
Victor Stinner331a6a52019-05-27 16:39:22 +02002420PyStatus
2421PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002422{
2423 _PyArgv args = {
2424 .argc = argc,
2425 .use_bytes_argv = 0,
2426 .bytes_argv = NULL,
2427 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002428 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002429}
2430
2431
Victor Stinner36242fd2019-07-01 19:13:50 +02002432PyStatus
2433PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2434 Py_ssize_t length, wchar_t **items)
2435{
2436 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2437 if (_PyStatus_EXCEPTION(status)) {
2438 return status;
2439 }
2440
2441 PyWideStringList list2 = {.length = length, .items = items};
2442 if (_PyWideStringList_Copy(list, &list2) < 0) {
2443 return _PyStatus_NO_MEMORY();
2444 }
2445 return _PyStatus_OK();
2446}
2447
2448
Victor Stinner331a6a52019-05-27 16:39:22 +02002449/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002450
2451 * Command line arguments
2452 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002453 * Py_xxx global configuration variables
2454
2455 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002456PyStatus
2457PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002458{
Victor Stinner331a6a52019-05-27 16:39:22 +02002459 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002460 PyWideStringList orig_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002461
Victor Stinner331a6a52019-05-27 16:39:22 +02002462 status = _Py_PreInitializeFromConfig(config, NULL);
2463 if (_PyStatus_EXCEPTION(status)) {
2464 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002465 }
2466
Victor Stinner331a6a52019-05-27 16:39:22 +02002467 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002468
Victor Stinner331a6a52019-05-27 16:39:22 +02002469 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2470 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002471 }
2472
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002473 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002474 status = core_read_precmdline(config, &precmdline);
2475 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002476 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002477 }
2478
Victor Stinner870b0352019-05-17 03:15:12 +02002479 assert(config->isolated >= 0);
2480 if (config->isolated) {
2481 config->use_environment = 0;
2482 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002483 }
2484
Victor Stinner331a6a52019-05-27 16:39:22 +02002485 status = config_read_cmdline(config);
2486 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002487 goto done;
2488 }
2489
Victor Stinner120b7072019-08-23 18:03:08 +01002490 /* Handle early PySys_AddXOption() calls */
2491 status = _PySys_ReadPreinitXOptions(config);
2492 if (_PyStatus_EXCEPTION(status)) {
2493 goto done;
2494 }
2495
Victor Stinner331a6a52019-05-27 16:39:22 +02002496 status = config_read(config);
2497 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002498 goto done;
2499 }
2500
Victor Stinnercab5d072019-05-17 19:01:14 +02002501 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002502 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002503 goto done;
2504 }
2505
2506 /* Check config consistency */
2507 assert(config->isolated >= 0);
2508 assert(config->use_environment >= 0);
2509 assert(config->dev_mode >= 0);
2510 assert(config->install_signal_handlers >= 0);
2511 assert(config->use_hash_seed >= 0);
2512 assert(config->faulthandler >= 0);
2513 assert(config->tracemalloc >= 0);
2514 assert(config->site_import >= 0);
2515 assert(config->bytes_warning >= 0);
2516 assert(config->inspect >= 0);
2517 assert(config->interactive >= 0);
2518 assert(config->optimization_level >= 0);
2519 assert(config->parser_debug >= 0);
2520 assert(config->write_bytecode >= 0);
2521 assert(config->verbose >= 0);
2522 assert(config->quiet >= 0);
2523 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002524 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002525 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002526 assert(config->buffered_stdio >= 0);
2527 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002528 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002529 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2530 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002531 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2532 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2533 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002534 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002535 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002536 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002537 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002538 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002539 assert(config->prefix != NULL);
2540 assert(config->base_prefix != NULL);
2541 assert(config->exec_prefix != NULL);
2542 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002543 }
2544 assert(config->filesystem_encoding != NULL);
2545 assert(config->filesystem_errors != NULL);
2546 assert(config->stdio_encoding != NULL);
2547 assert(config->stdio_errors != NULL);
2548#ifdef MS_WINDOWS
2549 assert(config->legacy_windows_stdio >= 0);
2550#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002551 /* -c and -m options are exclusive */
2552 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002553 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002554 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002555 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002556
Victor Stinner331a6a52019-05-27 16:39:22 +02002557 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002558
2559done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002560 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002561 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002562 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002563}
Victor Stinner1075d162019-03-25 23:19:57 +01002564
2565
2566PyObject*
2567_Py_GetConfigsAsDict(void)
2568{
Victor Stinner331a6a52019-05-27 16:39:22 +02002569 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002570 PyObject *dict = NULL;
2571
Victor Stinner331a6a52019-05-27 16:39:22 +02002572 result = PyDict_New();
2573 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002574 goto error;
2575 }
2576
Victor Stinner331a6a52019-05-27 16:39:22 +02002577 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002578 dict = _Py_GetGlobalVariablesAsDict();
2579 if (dict == NULL) {
2580 goto error;
2581 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002582 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002583 goto error;
2584 }
2585 Py_CLEAR(dict);
2586
2587 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002588 PyThreadState *tstate = _PyThreadState_GET();
2589 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002590 dict = _PyPreConfig_AsDict(pre_config);
2591 if (dict == NULL) {
2592 goto error;
2593 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002594 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002595 goto error;
2596 }
2597 Py_CLEAR(dict);
2598
2599 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002600 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinner331a6a52019-05-27 16:39:22 +02002601 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002602 if (dict == NULL) {
2603 goto error;
2604 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002605 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002606 goto error;
2607 }
2608 Py_CLEAR(dict);
2609
Victor Stinner331a6a52019-05-27 16:39:22 +02002610 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002611
2612error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002613 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002614 Py_XDECREF(dict);
2615 return NULL;
2616}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002617
2618
2619static void
2620init_dump_ascii_wstr(const wchar_t *str)
2621{
2622 if (str == NULL) {
2623 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002624 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002625 }
2626
2627 PySys_WriteStderr("'");
2628 for (; *str != L'\0'; str++) {
2629 wchar_t ch = *str;
2630 if (ch == L'\'') {
2631 PySys_WriteStderr("\\'");
2632 } else if (0x20 <= ch && ch < 0x7f) {
2633 PySys_WriteStderr("%lc", ch);
2634 }
2635 else if (ch <= 0xff) {
2636 PySys_WriteStderr("\\x%02x", ch);
2637 }
2638#if SIZEOF_WCHAR_T > 2
2639 else if (ch > 0xffff) {
2640 PySys_WriteStderr("\\U%08x", ch);
2641 }
2642#endif
2643 else {
2644 PySys_WriteStderr("\\u%04x", ch);
2645 }
2646 }
2647 PySys_WriteStderr("'");
2648}
2649
2650
2651/* Dump the Python path configuration into sys.stderr */
2652void
2653_Py_DumpPathConfig(PyThreadState *tstate)
2654{
2655 PyObject *exc_type, *exc_value, *exc_tb;
2656 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2657
2658 PySys_WriteStderr("Python path configuration:\n");
2659
2660#define DUMP_CONFIG(NAME, FIELD) \
2661 do { \
2662 PySys_WriteStderr(" " NAME " = "); \
2663 init_dump_ascii_wstr(config->FIELD); \
2664 PySys_WriteStderr("\n"); \
2665 } while (0)
2666
Victor Stinnerda7933e2020-04-13 03:04:28 +02002667 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002668 DUMP_CONFIG("PYTHONHOME", home);
2669 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2670 DUMP_CONFIG("program name", program_name);
2671 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2672 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2673 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2674 PySys_WriteStderr(" import site = %i\n", config->site_import);
2675#undef DUMP_CONFIG
2676
2677#define DUMP_SYS(NAME) \
2678 do { \
2679 obj = PySys_GetObject(#NAME); \
2680 PySys_FormatStderr(" sys.%s = ", #NAME); \
2681 if (obj != NULL) { \
2682 PySys_FormatStderr("%A", obj); \
2683 } \
2684 else { \
2685 PySys_WriteStderr("(not set)"); \
2686 } \
2687 PySys_FormatStderr("\n"); \
2688 } while (0)
2689
2690 PyObject *obj;
2691 DUMP_SYS(_base_executable);
2692 DUMP_SYS(base_prefix);
2693 DUMP_SYS(base_exec_prefix);
2694 DUMP_SYS(executable);
2695 DUMP_SYS(prefix);
2696 DUMP_SYS(exec_prefix);
2697#undef DUMP_SYS
2698
2699 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2700 if (sys_path != NULL && PyList_Check(sys_path)) {
2701 PySys_WriteStderr(" sys.path = [\n");
2702 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2703 for (Py_ssize_t i=0; i < len; i++) {
2704 PyObject *path = PyList_GET_ITEM(sys_path, i);
2705 PySys_FormatStderr(" %A,\n", path);
2706 }
2707 PySys_WriteStderr(" ]\n");
2708 }
2709
2710 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2711}