blob: 44250da99844c45d74a4492f50c251950dadb6ca [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\
Pablo Galindoc5fc1562020-04-22 23:29:27 +010071 -X oldparser: enable the traditional LL(1) parser; also PYTHONOLDPARSER\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000072 -X showrefcount: output the total reference count and number of used\n\
73 memory blocks when the program finishes or after each statement in the\n\
74 interactive interpreter. This only works on debug builds\n\
75 -X tracemalloc: start tracing Python memory allocations using the\n\
76 tracemalloc module. By default, only the most recent frame is stored in a\n\
77 traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\
78 traceback limit of NFRAME frames\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000079 -X importtime: show how long each import takes. It shows module name,\n\
80 cumulative time (including nested imports) and self time (excluding\n\
81 nested imports). Note that its output may be broken in multi-threaded\n\
82 application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
83 -X dev: enable CPythons development mode”, introducing additional runtime\n\
84 checks which are too expensive to be enabled by default. Effect of the\n\
85 developer mode:\n\
86 * Add default warning filter, as -W default\n\
87 * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\
88 * Enable the faulthandler module to dump the Python traceback on a crash\n\
89 * Enable asyncio debug mode\n\
90 * Set the dev_mode attribute of sys.flags to True\n\
91 * io.IOBase destructor logs close() exceptions\n\
92 -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\
93 locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\
94 otherwise activate automatically)\n\
95 -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
96 given directory instead of to the code tree\n\
97\n\
Victor Stinner95e2cbf2019-03-01 16:25:19 +010098--check-hash-based-pycs always|default|never:\n\
99 control how Python invalidates hash-based .pyc files\n\
100";
101static const char usage_4[] = "\
102file : program read from script file\n\
103- : program read from stdin (default; interactive mode if a tty)\n\
104arg ...: arguments passed to program in sys.argv[1:]\n\n\
105Other environment variables:\n\
106PYTHONSTARTUP: file executed on interactive startup (no default)\n\
107PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
108 default module search path. The result is sys.path.\n\
109";
110static const char usage_5[] =
111"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
112" The default module search path uses %s.\n"
113"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
Inada Naoki95826c72019-12-14 14:27:32 +0900114"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100115"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
116"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
117static const char usage_6[] =
118"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Serhiy Storchakae9c90aa2019-08-24 12:49:27 +0300119" to seed the hashes of str and bytes objects. It can also be set to an\n"
120" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100121" predictable seed.\n"
122"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
123" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
124" hooks.\n"
125"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
126" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
127" locale coercion and locale compatibility warnings on stderr.\n"
128"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
129" debugger. It can be set to the callable of your debugger of choice.\n"
130"PYTHONDEVMODE: enable the development mode.\n"
131"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
132
133#if defined(MS_WINDOWS)
134# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
135#else
136# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
137#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200138
139
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100140/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200141
Victor Stinner6c785c02018-08-01 17:56:14 +0200142/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200143 stdin and stdout error handler to "surrogateescape". */
144int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200145int Py_DebugFlag = 0; /* Needed by parser.c */
146int Py_VerboseFlag = 0; /* Needed by import.c */
147int Py_QuietFlag = 0; /* Needed by sysmodule.c */
148int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
149int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
150int Py_OptimizeFlag = 0; /* Needed by compile.c */
151int Py_NoSiteFlag = 0; /* Suppress 'import site' */
152int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
153int Py_FrozenFlag = 0; /* Needed by getpath.c */
154int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
155int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
156int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
157int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
158int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
159int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
160#ifdef MS_WINDOWS
161int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
162int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
163#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200164
165
Victor Stinner1075d162019-03-25 23:19:57 +0100166static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100167_Py_GetGlobalVariablesAsDict(void)
168{
169 PyObject *dict, *obj;
170
171 dict = PyDict_New();
172 if (dict == NULL) {
173 return NULL;
174 }
175
176#define SET_ITEM(KEY, EXPR) \
177 do { \
178 obj = (EXPR); \
179 if (obj == NULL) { \
180 return NULL; \
181 } \
182 int res = PyDict_SetItemString(dict, (KEY), obj); \
183 Py_DECREF(obj); \
184 if (res < 0) { \
185 goto fail; \
186 } \
187 } while (0)
188#define SET_ITEM_INT(VAR) \
189 SET_ITEM(#VAR, PyLong_FromLong(VAR))
190#define FROM_STRING(STR) \
191 ((STR != NULL) ? \
192 PyUnicode_FromString(STR) \
193 : (Py_INCREF(Py_None), Py_None))
194#define SET_ITEM_STR(VAR) \
195 SET_ITEM(#VAR, FROM_STRING(VAR))
196
197 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
198 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
199 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
200 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
201
202 SET_ITEM_INT(Py_UTF8Mode);
203 SET_ITEM_INT(Py_DebugFlag);
204 SET_ITEM_INT(Py_VerboseFlag);
205 SET_ITEM_INT(Py_QuietFlag);
206 SET_ITEM_INT(Py_InteractiveFlag);
207 SET_ITEM_INT(Py_InspectFlag);
208
209 SET_ITEM_INT(Py_OptimizeFlag);
210 SET_ITEM_INT(Py_NoSiteFlag);
211 SET_ITEM_INT(Py_BytesWarningFlag);
212 SET_ITEM_INT(Py_FrozenFlag);
213 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
214 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
215 SET_ITEM_INT(Py_NoUserSiteDirectory);
216 SET_ITEM_INT(Py_UnbufferedStdioFlag);
217 SET_ITEM_INT(Py_HashRandomizationFlag);
218 SET_ITEM_INT(Py_IsolatedFlag);
219
220#ifdef MS_WINDOWS
221 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
222 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
223#endif
224
225 return dict;
226
227fail:
228 Py_DECREF(dict);
229 return NULL;
230
231#undef FROM_STRING
232#undef SET_ITEM
233#undef SET_ITEM_INT
234#undef SET_ITEM_STR
235}
236
237
Victor Stinner331a6a52019-05-27 16:39:22 +0200238/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200239
Victor Stinner331a6a52019-05-27 16:39:22 +0200240PyStatus PyStatus_Ok(void)
241{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200242
Victor Stinner331a6a52019-05-27 16:39:22 +0200243PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200244{
Victor Stinner331a6a52019-05-27 16:39:22 +0200245 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner871ff772019-05-17 23:54:00 +0200246 .err_msg = err_msg};
247}
248
Victor Stinner331a6a52019-05-27 16:39:22 +0200249PyStatus PyStatus_NoMemory(void)
250{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200251
Victor Stinner331a6a52019-05-27 16:39:22 +0200252PyStatus PyStatus_Exit(int exitcode)
253{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200254
255
Victor Stinner331a6a52019-05-27 16:39:22 +0200256int PyStatus_IsError(PyStatus status)
257{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200258
Victor Stinner331a6a52019-05-27 16:39:22 +0200259int PyStatus_IsExit(PyStatus status)
260{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200261
Victor Stinner331a6a52019-05-27 16:39:22 +0200262int PyStatus_Exception(PyStatus status)
263{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200264
265
Victor Stinner331a6a52019-05-27 16:39:22 +0200266/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100267
268#ifndef NDEBUG
269int
Victor Stinner331a6a52019-05-27 16:39:22 +0200270_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100271{
272 assert(list->length >= 0);
273 if (list->length != 0) {
274 assert(list->items != NULL);
275 }
276 for (Py_ssize_t i = 0; i < list->length; i++) {
277 assert(list->items[i] != NULL);
278 }
279 return 1;
280}
281#endif /* Py_DEBUG */
282
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100283
Victor Stinner6c785c02018-08-01 17:56:14 +0200284void
Victor Stinner331a6a52019-05-27 16:39:22 +0200285_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200286{
Victor Stinner331a6a52019-05-27 16:39:22 +0200287 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100288 for (Py_ssize_t i=0; i < list->length; i++) {
289 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200290 }
Victor Stinner74f65682019-03-15 15:08:05 +0100291 PyMem_RawFree(list->items);
292 list->length = 0;
293 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200294}
295
296
Victor Stinner74f65682019-03-15 15:08:05 +0100297int
Victor Stinner331a6a52019-05-27 16:39:22 +0200298_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200299{
Victor Stinner331a6a52019-05-27 16:39:22 +0200300 assert(_PyWideStringList_CheckConsistency(list));
301 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100302
303 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200304 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100305 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300306 }
Victor Stinner74f65682019-03-15 15:08:05 +0100307
Victor Stinnerfb4ae152019-09-30 01:40:17 +0200308 PyWideStringList copy = _PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100309
310 size_t size = list2->length * sizeof(list2->items[0]);
311 copy.items = PyMem_RawMalloc(size);
312 if (copy.items == NULL) {
313 return -1;
314 }
315
316 for (Py_ssize_t i=0; i < list2->length; i++) {
317 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
318 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200319 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100320 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200321 }
Victor Stinner74f65682019-03-15 15:08:05 +0100322 copy.items[i] = item;
323 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200324 }
Victor Stinner74f65682019-03-15 15:08:05 +0100325
Victor Stinner331a6a52019-05-27 16:39:22 +0200326 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100327 *list = copy;
328 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200329}
330
331
Victor Stinner331a6a52019-05-27 16:39:22 +0200332PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100333PyWideStringList_Insert(PyWideStringList *list,
334 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100335{
Victor Stinner3842f292019-08-23 16:57:54 +0100336 Py_ssize_t len = list->length;
337 if (len == PY_SSIZE_T_MAX) {
Min ho Kim96e12d52019-07-22 06:12:33 +1000338 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200339 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100340 }
Victor Stinner3842f292019-08-23 16:57:54 +0100341 if (index < 0) {
342 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
343 }
344 if (index > len) {
345 index = len;
346 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100347
Victor Stinner74f65682019-03-15 15:08:05 +0100348 wchar_t *item2 = _PyMem_RawWcsdup(item);
349 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200350 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100351 }
Victor Stinner74f65682019-03-15 15:08:05 +0100352
Victor Stinner3842f292019-08-23 16:57:54 +0100353 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100354 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
355 if (items2 == NULL) {
356 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200357 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100358 }
359
Victor Stinner3842f292019-08-23 16:57:54 +0100360 if (index < len) {
361 memmove(&items2[index + 1],
362 &items2[index],
363 (len - index) * sizeof(items2[0]));
364 }
365
366 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100367 list->items = items2;
368 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200369 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100370}
371
372
Victor Stinner331a6a52019-05-27 16:39:22 +0200373PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100374PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
375{
376 return PyWideStringList_Insert(list, list->length, item);
377}
378
379
380PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200381_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100382{
383 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200384 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
385 if (_PyStatus_EXCEPTION(status)) {
386 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100387 }
388 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200389 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100390}
391
392
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100393static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200394_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100395{
396 for (Py_ssize_t i = 0; i < list->length; i++) {
397 if (wcscmp(list->items[i], item) == 0) {
398 return 1;
399 }
400 }
401 return 0;
402}
403
404
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100405PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200406_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100407{
Victor Stinner331a6a52019-05-27 16:39:22 +0200408 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100409
Victor Stinner74f65682019-03-15 15:08:05 +0100410 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100411 if (pylist == NULL) {
412 return NULL;
413 }
414
Victor Stinner74f65682019-03-15 15:08:05 +0100415 for (Py_ssize_t i = 0; i < list->length; i++) {
416 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
417 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100418 Py_DECREF(pylist);
419 return NULL;
420 }
Victor Stinner74f65682019-03-15 15:08:05 +0100421 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100422 }
423 return pylist;
424}
425
426
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100427/* --- Py_SetStandardStreamEncoding() ----------------------------- */
428
Victor Stinner124b9eb2018-08-29 01:29:06 +0200429/* Helper to allow an embedding application to override the normal
430 * mechanism that attempts to figure out an appropriate IO encoding
431 */
432
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200433static char *_Py_StandardStreamEncoding = NULL;
434static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200435
436int
437Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
438{
439 if (Py_IsInitialized()) {
440 /* This is too late to have any effect */
441 return -1;
442 }
443
444 int res = 0;
445
446 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
447 but Py_Initialize() can change the allocator. Use a known allocator
448 to be able to release the memory later. */
449 PyMemAllocatorEx old_alloc;
450 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
451
452 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
453 * initialised yet.
454 *
455 * However, the raw memory allocators are initialised appropriately
456 * as C static variables, so _PyMem_RawStrdup is OK even though
457 * Py_Initialize hasn't been called yet.
458 */
459 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200460 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200461 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
462 if (!_Py_StandardStreamEncoding) {
463 res = -2;
464 goto done;
465 }
466 }
467 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200468 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200469 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
470 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200471 PyMem_RawFree(_Py_StandardStreamEncoding);
472 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200473 res = -3;
474 goto done;
475 }
476 }
477#ifdef MS_WINDOWS
478 if (_Py_StandardStreamEncoding) {
479 /* Overriding the stream encoding implies legacy streams */
480 Py_LegacyWindowsStdioFlag = 1;
481 }
482#endif
483
484done:
485 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
486
487 return res;
488}
489
490
491void
492_Py_ClearStandardStreamEncoding(void)
493{
494 /* Use the same allocator than Py_SetStandardStreamEncoding() */
495 PyMemAllocatorEx old_alloc;
496 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
497
498 /* We won't need them anymore. */
499 if (_Py_StandardStreamEncoding) {
500 PyMem_RawFree(_Py_StandardStreamEncoding);
501 _Py_StandardStreamEncoding = NULL;
502 }
503 if (_Py_StandardStreamErrors) {
504 PyMem_RawFree(_Py_StandardStreamErrors);
505 _Py_StandardStreamErrors = NULL;
506 }
507
508 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
509}
510
511
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100512/* --- Py_GetArgcArgv() ------------------------------------------- */
513
514/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200515static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100516
517
518void
519_Py_ClearArgcArgv(void)
520{
521 PyMemAllocatorEx old_alloc;
522 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
523
Victor Stinner331a6a52019-05-27 16:39:22 +0200524 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100525
526 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
527}
528
529
Victor Stinner4fffd382019-03-06 01:44:31 +0100530static int
Victor Stinner74f65682019-03-15 15:08:05 +0100531_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100532{
Victor Stinner331a6a52019-05-27 16:39:22 +0200533 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100534 int res;
535
536 PyMemAllocatorEx old_alloc;
537 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
538
Victor Stinner331a6a52019-05-27 16:39:22 +0200539 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100540
541 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
542 return res;
543}
544
545
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100546void
547Py_GetArgcArgv(int *argc, wchar_t ***argv)
548{
Victor Stinner74f65682019-03-15 15:08:05 +0100549 *argc = (int)orig_argv.length;
550 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100551}
552
553
Victor Stinner331a6a52019-05-27 16:39:22 +0200554/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100555
556#define DECODE_LOCALE_ERR(NAME, LEN) \
557 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200558 ? _PyStatus_ERR("cannot decode " NAME) \
559 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100560
Victor Stinner441b10c2019-09-28 04:28:35 +0200561
Victor Stinner6c785c02018-08-01 17:56:14 +0200562/* Free memory allocated in config, but don't clear all attributes */
563void
Victor Stinner331a6a52019-05-27 16:39:22 +0200564PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200565{
566#define CLEAR(ATTR) \
567 do { \
568 PyMem_RawFree(ATTR); \
569 ATTR = NULL; \
570 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200571
572 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200573 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200574 CLEAR(config->home);
575 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200576
Victor Stinner331a6a52019-05-27 16:39:22 +0200577 _PyWideStringList_Clear(&config->argv);
578 _PyWideStringList_Clear(&config->warnoptions);
579 _PyWideStringList_Clear(&config->xoptions);
580 _PyWideStringList_Clear(&config->module_search_paths);
581 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200582
583 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700584 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200585 CLEAR(config->prefix);
586 CLEAR(config->base_prefix);
587 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200588 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200589
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200590 CLEAR(config->filesystem_encoding);
591 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200592 CLEAR(config->stdio_encoding);
593 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100594 CLEAR(config->run_command);
595 CLEAR(config->run_module);
596 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400597 CLEAR(config->check_hash_pycs_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200598#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200599}
600
601
Victor Stinner8462a492019-10-01 12:06:16 +0200602void
Victor Stinner331a6a52019-05-27 16:39:22 +0200603_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200604{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200605 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200606
Victor Stinner022be022019-05-22 23:58:50 +0200607 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200608 config->isolated = -1;
609 config->use_environment = -1;
610 config->dev_mode = -1;
611 config->install_signal_handlers = 1;
612 config->use_hash_seed = -1;
613 config->faulthandler = -1;
614 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200615 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200616 config->parse_argv = 0;
617 config->site_import = -1;
618 config->bytes_warning = -1;
619 config->inspect = -1;
620 config->interactive = -1;
621 config->optimization_level = -1;
622 config->parser_debug= -1;
623 config->write_bytecode = -1;
624 config->verbose = -1;
625 config->quiet = -1;
626 config->user_site_directory = -1;
627 config->configure_c_stdio = 0;
628 config->buffered_stdio = -1;
629 config->_install_importlib = 1;
630 config->check_hash_pycs_mode = NULL;
631 config->pathconfig_warnings = -1;
632 config->_init_main = 1;
Victor Stinner252346a2020-05-01 11:33:44 +0200633 config->_isolated_interpreter = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200634#ifdef MS_WINDOWS
635 config->legacy_windows_stdio = -1;
636#endif
Victor Stinner1def7752020-04-23 03:03:24 +0200637 config->_use_peg_parser = 1;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200638}
639
640
Victor Stinner8462a492019-10-01 12:06:16 +0200641static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200642config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200643{
Victor Stinner8462a492019-10-01 12:06:16 +0200644 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200645
646 config->isolated = 0;
647 config->use_environment = 1;
648 config->site_import = 1;
649 config->bytes_warning = 0;
650 config->inspect = 0;
651 config->interactive = 0;
652 config->optimization_level = 0;
653 config->parser_debug= 0;
654 config->write_bytecode = 1;
655 config->verbose = 0;
656 config->quiet = 0;
657 config->user_site_directory = 1;
658 config->buffered_stdio = 1;
659 config->pathconfig_warnings = 1;
660#ifdef MS_WINDOWS
661 config->legacy_windows_stdio = 0;
662#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200663}
664
665
Victor Stinner8462a492019-10-01 12:06:16 +0200666void
Victor Stinner331a6a52019-05-27 16:39:22 +0200667PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200668{
Victor Stinner8462a492019-10-01 12:06:16 +0200669 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200670
Victor Stinner022be022019-05-22 23:58:50 +0200671 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200672 config->configure_c_stdio = 1;
673 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200674}
675
676
Victor Stinner8462a492019-10-01 12:06:16 +0200677void
Victor Stinner331a6a52019-05-27 16:39:22 +0200678PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200679{
Victor Stinner8462a492019-10-01 12:06:16 +0200680 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200681
Victor Stinner022be022019-05-22 23:58:50 +0200682 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200683 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200684 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200685 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200686 config->dev_mode = 0;
687 config->install_signal_handlers = 0;
688 config->use_hash_seed = 0;
689 config->faulthandler = 0;
690 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200691 config->pathconfig_warnings = 0;
692#ifdef MS_WINDOWS
693 config->legacy_windows_stdio = 0;
694#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200695}
696
697
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200698/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200699PyStatus
700PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200701{
Victor Stinner331a6a52019-05-27 16:39:22 +0200702 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
703 if (_PyStatus_EXCEPTION(status)) {
704 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200705 }
706
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200707 wchar_t *str2;
708 if (str != NULL) {
709 str2 = _PyMem_RawWcsdup(str);
710 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200711 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200712 }
713 }
714 else {
715 str2 = NULL;
716 }
717 PyMem_RawFree(*config_str);
718 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200719 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200720}
721
722
Victor Stinner331a6a52019-05-27 16:39:22 +0200723static PyStatus
724config_set_bytes_string(PyConfig *config, wchar_t **config_str,
725 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200726{
Victor Stinner331a6a52019-05-27 16:39:22 +0200727 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
728 if (_PyStatus_EXCEPTION(status)) {
729 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400730 }
731
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200732 wchar_t *str2;
733 if (str != NULL) {
734 size_t len;
735 str2 = Py_DecodeLocale(str, &len);
736 if (str2 == NULL) {
737 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200738 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200739 }
740 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200741 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200742 }
743 }
744 }
745 else {
746 str2 = NULL;
747 }
748 PyMem_RawFree(*config_str);
749 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200750 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200751}
752
753
Victor Stinner331a6a52019-05-27 16:39:22 +0200754#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
755 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400756
757
Victor Stinner70005ac2019-05-02 15:25:34 -0400758/* Decode str using Py_DecodeLocale() and set the result into *config_str.
759 Pre-initialize Python if needed to ensure that encodings are properly
760 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200761PyStatus
762PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200763 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400764{
Victor Stinner331a6a52019-05-27 16:39:22 +0200765 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400766}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200767
768
Victor Stinner331a6a52019-05-27 16:39:22 +0200769PyStatus
770_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200771{
Victor Stinner331a6a52019-05-27 16:39:22 +0200772 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200773
Victor Stinner331a6a52019-05-27 16:39:22 +0200774 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200775
776#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200777#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200778 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200779 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
780 if (_PyStatus_EXCEPTION(status)) { \
781 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200782 } \
783 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100784#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200785 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200786 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200787 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200788 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200789 } while (0)
790
Victor Stinner6d1c4672019-05-20 11:02:00 +0200791 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100792 COPY_ATTR(isolated);
793 COPY_ATTR(use_environment);
794 COPY_ATTR(dev_mode);
Victor Stinner1def7752020-04-23 03:03:24 +0200795 COPY_ATTR(_use_peg_parser);
Victor Stinner6c785c02018-08-01 17:56:14 +0200796 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200797 COPY_ATTR(use_hash_seed);
798 COPY_ATTR(hash_seed);
799 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200800 COPY_ATTR(faulthandler);
801 COPY_ATTR(tracemalloc);
802 COPY_ATTR(import_time);
803 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200804 COPY_ATTR(dump_refs);
805 COPY_ATTR(malloc_stats);
806
Victor Stinner124b9eb2018-08-29 01:29:06 +0200807 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200808 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200809 COPY_WSTR_ATTR(home);
810 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200811
Victor Stinnerae239f62019-05-16 17:02:56 +0200812 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100813 COPY_WSTRLIST(argv);
814 COPY_WSTRLIST(warnoptions);
815 COPY_WSTRLIST(xoptions);
816 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200817 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200818
Victor Stinner124b9eb2018-08-29 01:29:06 +0200819 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700820 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200821 COPY_WSTR_ATTR(prefix);
822 COPY_WSTR_ATTR(base_prefix);
823 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200824 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200825
Victor Stinner6c785c02018-08-01 17:56:14 +0200826 COPY_ATTR(site_import);
827 COPY_ATTR(bytes_warning);
828 COPY_ATTR(inspect);
829 COPY_ATTR(interactive);
830 COPY_ATTR(optimization_level);
831 COPY_ATTR(parser_debug);
832 COPY_ATTR(write_bytecode);
833 COPY_ATTR(verbose);
834 COPY_ATTR(quiet);
835 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200836 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200837 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400838 COPY_WSTR_ATTR(filesystem_encoding);
839 COPY_WSTR_ATTR(filesystem_errors);
840 COPY_WSTR_ATTR(stdio_encoding);
841 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200842#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200843 COPY_ATTR(legacy_windows_stdio);
844#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100845 COPY_ATTR(skip_source_first_line);
846 COPY_WSTR_ATTR(run_command);
847 COPY_WSTR_ATTR(run_module);
848 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400849 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200850 COPY_ATTR(pathconfig_warnings);
851 COPY_ATTR(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200852 COPY_ATTR(_isolated_interpreter);
Victor Stinnerdedaac02020-06-08 18:44:50 +0200853 COPY_WSTRLIST(_orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200854
855#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200856#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200857#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200858 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200859}
860
861
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100862static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200863config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100864{
865 PyObject *dict;
866
867 dict = PyDict_New();
868 if (dict == NULL) {
869 return NULL;
870 }
871
872#define SET_ITEM(KEY, EXPR) \
873 do { \
874 PyObject *obj = (EXPR); \
875 if (obj == NULL) { \
876 goto fail; \
877 } \
878 int res = PyDict_SetItemString(dict, (KEY), obj); \
879 Py_DECREF(obj); \
880 if (res < 0) { \
881 goto fail; \
882 } \
883 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100884#define SET_ITEM_INT(ATTR) \
885 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
886#define SET_ITEM_UINT(ATTR) \
887 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100888#define FROM_WSTRING(STR) \
889 ((STR != NULL) ? \
890 PyUnicode_FromWideChar(STR, -1) \
891 : (Py_INCREF(Py_None), Py_None))
892#define SET_ITEM_WSTR(ATTR) \
893 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
894#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200895 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100896
Victor Stinner6d1c4672019-05-20 11:02:00 +0200897 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100898 SET_ITEM_INT(isolated);
899 SET_ITEM_INT(use_environment);
900 SET_ITEM_INT(dev_mode);
Victor Stinner1def7752020-04-23 03:03:24 +0200901 SET_ITEM_INT(_use_peg_parser);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100902 SET_ITEM_INT(install_signal_handlers);
903 SET_ITEM_INT(use_hash_seed);
904 SET_ITEM_UINT(hash_seed);
905 SET_ITEM_INT(faulthandler);
906 SET_ITEM_INT(tracemalloc);
907 SET_ITEM_INT(import_time);
908 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100909 SET_ITEM_INT(dump_refs);
910 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400911 SET_ITEM_WSTR(filesystem_encoding);
912 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100913 SET_ITEM_WSTR(pycache_prefix);
914 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200915 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100916 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100917 SET_ITEM_WSTRLIST(xoptions);
918 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200919 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100920 SET_ITEM_WSTR(home);
921 SET_ITEM_WSTRLIST(module_search_paths);
922 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700923 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100924 SET_ITEM_WSTR(prefix);
925 SET_ITEM_WSTR(base_prefix);
926 SET_ITEM_WSTR(exec_prefix);
927 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100928 SET_ITEM_INT(site_import);
929 SET_ITEM_INT(bytes_warning);
930 SET_ITEM_INT(inspect);
931 SET_ITEM_INT(interactive);
932 SET_ITEM_INT(optimization_level);
933 SET_ITEM_INT(parser_debug);
934 SET_ITEM_INT(write_bytecode);
935 SET_ITEM_INT(verbose);
936 SET_ITEM_INT(quiet);
937 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200938 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100939 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400940 SET_ITEM_WSTR(stdio_encoding);
941 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100942#ifdef MS_WINDOWS
943 SET_ITEM_INT(legacy_windows_stdio);
944#endif
945 SET_ITEM_INT(skip_source_first_line);
946 SET_ITEM_WSTR(run_command);
947 SET_ITEM_WSTR(run_module);
948 SET_ITEM_WSTR(run_filename);
949 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400950 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200951 SET_ITEM_INT(pathconfig_warnings);
952 SET_ITEM_INT(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200953 SET_ITEM_INT(_isolated_interpreter);
Victor Stinnerdedaac02020-06-08 18:44:50 +0200954 SET_ITEM_WSTRLIST(_orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100955
956 return dict;
957
958fail:
959 Py_DECREF(dict);
960 return NULL;
961
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100962#undef FROM_WSTRING
963#undef SET_ITEM
964#undef SET_ITEM_INT
965#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100966#undef SET_ITEM_WSTR
967#undef SET_ITEM_WSTRLIST
968}
969
970
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100971static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200972config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200973{
Victor Stinner20004952019-03-26 02:31:11 +0100974 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200975}
976
977
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100978/* Get a copy of the environment variable as wchar_t*.
979 Return 0 on success, but *dest can be NULL.
980 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200981static PyStatus
982config_get_env_dup(PyConfig *config,
983 wchar_t **dest,
984 wchar_t *wname, char *name,
985 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200986{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200987 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100988 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200989
Victor Stinner20004952019-03-26 02:31:11 +0100990 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200991 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200992 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200993 }
994
995#ifdef MS_WINDOWS
996 const wchar_t *var = _wgetenv(wname);
997 if (!var || var[0] == '\0') {
998 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200999 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001000 }
1001
Victor Stinner331a6a52019-05-27 16:39:22 +02001002 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +02001003#else
1004 const char *var = getenv(name);
1005 if (!var || var[0] == '\0') {
1006 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001007 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001008 }
1009
Victor Stinner331a6a52019-05-27 16:39:22 +02001010 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001011#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001012}
1013
1014
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001015#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001016 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001017
1018
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001019static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001020config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001021{
Victor Stinner022be022019-05-22 23:58:50 +02001022 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1023 /* Python and Isolated configuration ignore global variables */
1024 return;
1025 }
1026
Victor Stinner6c785c02018-08-01 17:56:14 +02001027#define COPY_FLAG(ATTR, VALUE) \
1028 if (config->ATTR == -1) { \
1029 config->ATTR = VALUE; \
1030 }
1031#define COPY_NOT_FLAG(ATTR, VALUE) \
1032 if (config->ATTR == -1) { \
1033 config->ATTR = !(VALUE); \
1034 }
1035
Victor Stinner20004952019-03-26 02:31:11 +01001036 COPY_FLAG(isolated, Py_IsolatedFlag);
1037 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001038 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1039 COPY_FLAG(inspect, Py_InspectFlag);
1040 COPY_FLAG(interactive, Py_InteractiveFlag);
1041 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1042 COPY_FLAG(parser_debug, Py_DebugFlag);
1043 COPY_FLAG(verbose, Py_VerboseFlag);
1044 COPY_FLAG(quiet, Py_QuietFlag);
1045#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001046 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1047#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001048 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001049
Victor Stinner6c785c02018-08-01 17:56:14 +02001050 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1051 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1052 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1053 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1054
Victor Stinner6c785c02018-08-01 17:56:14 +02001055#undef COPY_FLAG
1056#undef COPY_NOT_FLAG
1057}
1058
1059
1060/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001061static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001062config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001063{
1064#define COPY_FLAG(ATTR, VAR) \
1065 if (config->ATTR != -1) { \
1066 VAR = config->ATTR; \
1067 }
1068#define COPY_NOT_FLAG(ATTR, VAR) \
1069 if (config->ATTR != -1) { \
1070 VAR = !config->ATTR; \
1071 }
1072
Victor Stinner20004952019-03-26 02:31:11 +01001073 COPY_FLAG(isolated, Py_IsolatedFlag);
1074 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001075 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1076 COPY_FLAG(inspect, Py_InspectFlag);
1077 COPY_FLAG(interactive, Py_InteractiveFlag);
1078 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1079 COPY_FLAG(parser_debug, Py_DebugFlag);
1080 COPY_FLAG(verbose, Py_VerboseFlag);
1081 COPY_FLAG(quiet, Py_QuietFlag);
1082#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001083 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1084#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001085 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001086
Victor Stinner6c785c02018-08-01 17:56:14 +02001087 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1088 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1089 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1090 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1091
Victor Stinner6c785c02018-08-01 17:56:14 +02001092 /* Random or non-zero hash seed */
1093 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1094 config->hash_seed != 0);
1095
1096#undef COPY_FLAG
1097#undef COPY_NOT_FLAG
1098}
1099
1100
1101/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1102 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001103static PyStatus
1104config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001105{
Victor Stinner331a6a52019-05-27 16:39:22 +02001106 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001107
Victor Stinner6c785c02018-08-01 17:56:14 +02001108 /* If Py_SetProgramName() was called, use its value */
1109 const wchar_t *program_name = _Py_path_config.program_name;
1110 if (program_name != NULL) {
1111 config->program_name = _PyMem_RawWcsdup(program_name);
1112 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001113 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001114 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001115 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001116 }
1117
1118#ifdef __APPLE__
1119 /* On MacOS X, when the Python interpreter is embedded in an
1120 application bundle, it gets executed by a bootstrapping script
1121 that does os.execve() with an argv[0] that's different from the
1122 actual Python executable. This is needed to keep the Finder happy,
1123 or rather, to work around Apple's overly strict requirements of
1124 the process name. However, we still need a usable sys.executable,
1125 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001126 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001127 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001128 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001129 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001130 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1131 "PYTHONEXECUTABLE environment variable");
1132 if (_PyStatus_EXCEPTION(status)) {
1133 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001134 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001135 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001136 }
1137#ifdef WITH_NEXT_FRAMEWORK
1138 else {
1139 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1140 if (pyvenv_launcher && *pyvenv_launcher) {
1141 /* Used by Mac/Tools/pythonw.c to forward
1142 * the argv0 of the stub executable
1143 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001144 status = CONFIG_SET_BYTES_STR(config,
1145 &config->program_name,
1146 pyvenv_launcher,
1147 "__PYVENV_LAUNCHER__ environment variable");
1148 if (_PyStatus_EXCEPTION(status)) {
1149 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001150 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001151
1152 /*
1153 * This environment variable is used to communicate between
1154 * the stub launcher and the real interpreter and isn't needed
1155 * beyond this point.
1156 *
1157 * Clean up to avoid problems when launching other programs
1158 * later on.
1159 */
1160 (void)unsetenv("__PYVENV_LAUNCHER__");
1161
Victor Stinner331a6a52019-05-27 16:39:22 +02001162 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001163 }
1164 }
1165#endif /* WITH_NEXT_FRAMEWORK */
1166#endif /* __APPLE__ */
1167
Victor Stinnerfed02e12019-05-17 11:12:09 +02001168 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001169 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001170 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1171 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1172 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001173 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001174 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001175 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001176 }
1177
Victor Stinnerfed02e12019-05-17 11:12:09 +02001178 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001179#ifdef MS_WINDOWS
1180 const wchar_t *default_program_name = L"python";
1181#else
1182 const wchar_t *default_program_name = L"python3";
1183#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001184 status = PyConfig_SetString(config, &config->program_name,
1185 default_program_name);
1186 if (_PyStatus_EXCEPTION(status)) {
1187 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001188 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001189 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001190}
1191
Victor Stinner331a6a52019-05-27 16:39:22 +02001192static PyStatus
1193config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001194{
1195 assert(config->executable == NULL);
1196
1197 /* If Py_SetProgramFullPath() was called, use its value */
1198 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1199 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001200 PyStatus status = PyConfig_SetString(config,
1201 &config->executable,
1202 program_full_path);
1203 if (_PyStatus_EXCEPTION(status)) {
1204 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001205 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001206 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001207 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001208 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001209}
Victor Stinner6c785c02018-08-01 17:56:14 +02001210
Victor Stinner4fffd382019-03-06 01:44:31 +01001211
Victor Stinner6c785c02018-08-01 17:56:14 +02001212static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001213config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001214{
Victor Stinner74f65682019-03-15 15:08:05 +01001215 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001216}
1217
1218
Victor Stinner331a6a52019-05-27 16:39:22 +02001219static PyStatus
1220config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001221{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001222 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001223
1224 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001225 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001226 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001227 PyStatus status = PyConfig_SetString(config, &config->home, home);
1228 if (_PyStatus_EXCEPTION(status)) {
1229 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001230 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001231 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001232 }
1233
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001234 return CONFIG_GET_ENV_DUP(config, &config->home,
1235 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001236}
1237
1238
Victor Stinner331a6a52019-05-27 16:39:22 +02001239static PyStatus
1240config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001241{
Victor Stinner331a6a52019-05-27 16:39:22 +02001242 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001243
1244 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1245 /* Convert a text seed to a numeric one */
1246 if (seed_text && strcmp(seed_text, "random") != 0) {
1247 const char *endptr = seed_text;
1248 unsigned long seed;
1249 errno = 0;
1250 seed = strtoul(seed_text, (char **)&endptr, 10);
1251 if (*endptr != '\0'
1252 || seed > 4294967295UL
1253 || (errno == ERANGE && seed == ULONG_MAX))
1254 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001255 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001256 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001257 }
1258 /* Use a specific hash */
1259 config->use_hash_seed = 1;
1260 config->hash_seed = seed;
1261 }
1262 else {
1263 /* Use a random hash */
1264 config->use_hash_seed = 0;
1265 config->hash_seed = 0;
1266 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001267 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001268}
1269
1270
Victor Stinner6c785c02018-08-01 17:56:14 +02001271static int
1272config_wstr_to_int(const wchar_t *wstr, int *result)
1273{
1274 const wchar_t *endptr = wstr;
1275 errno = 0;
1276 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1277 if (*endptr != '\0' || errno == ERANGE) {
1278 return -1;
1279 }
1280 if (value < INT_MIN || value > INT_MAX) {
1281 return -1;
1282 }
1283
1284 *result = (int)value;
1285 return 0;
1286}
1287
1288
Victor Stinner331a6a52019-05-27 16:39:22 +02001289static PyStatus
1290config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001291{
Victor Stinner331a6a52019-05-27 16:39:22 +02001292 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001293 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001294
Victor Stinner6c785c02018-08-01 17:56:14 +02001295 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001296 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1297 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1298 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1299 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001300
1301 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001302 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001303 if (dont_write_bytecode) {
1304 config->write_bytecode = 0;
1305 }
1306
1307 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001308 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001309 if (no_user_site_directory) {
1310 config->user_site_directory = 0;
1311 }
1312
1313 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001314 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001315 if (unbuffered_stdio) {
1316 config->buffered_stdio = 0;
1317 }
1318
1319#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001320 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001321 "PYTHONLEGACYWINDOWSSTDIO");
1322#endif
1323
Victor Stinner331a6a52019-05-27 16:39:22 +02001324 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001325 config->dump_refs = 1;
1326 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001327 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001328 config->malloc_stats = 1;
1329 }
1330
Victor Stinner331a6a52019-05-27 16:39:22 +02001331 if (config->pythonpath_env == NULL) {
1332 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1333 L"PYTHONPATH", "PYTHONPATH");
1334 if (_PyStatus_EXCEPTION(status)) {
1335 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001336 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001337 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001338
1339 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001340 status = config_init_hash_seed(config);
1341 if (_PyStatus_EXCEPTION(status)) {
1342 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001343 }
1344 }
1345
Victor Stinner331a6a52019-05-27 16:39:22 +02001346 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001347}
1348
1349
Victor Stinner331a6a52019-05-27 16:39:22 +02001350static PyStatus
1351config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001352{
1353 int nframe;
1354 int valid;
1355
Victor Stinner331a6a52019-05-27 16:39:22 +02001356 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001357 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001358 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001359 valid = (nframe >= 0);
1360 }
1361 else {
1362 valid = 0;
1363 }
1364 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001365 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001366 }
1367 config->tracemalloc = nframe;
1368 }
1369
1370 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1371 if (xoption) {
1372 const wchar_t *sep = wcschr(xoption, L'=');
1373 if (sep) {
1374 if (!config_wstr_to_int(sep + 1, &nframe)) {
1375 valid = (nframe >= 0);
1376 }
1377 else {
1378 valid = 0;
1379 }
1380 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001381 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1382 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001383 }
1384 }
1385 else {
1386 /* -X tracemalloc behaves as -X tracemalloc=1 */
1387 nframe = 1;
1388 }
1389 config->tracemalloc = nframe;
1390 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001391 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001392}
1393
1394
Victor Stinner331a6a52019-05-27 16:39:22 +02001395static PyStatus
1396config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001397{
1398 assert(config->pycache_prefix == NULL);
1399
1400 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1401 if (xoption) {
1402 const wchar_t *sep = wcschr(xoption, L'=');
1403 if (sep && wcslen(sep) > 1) {
1404 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1405 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001406 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001407 }
1408 }
1409 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001410 // PYTHONPYCACHEPREFIX env var ignored
1411 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001412 config->pycache_prefix = NULL;
1413 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001414 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001415 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001416
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001417 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1418 L"PYTHONPYCACHEPREFIX",
1419 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001420}
1421
1422
Victor Stinner331a6a52019-05-27 16:39:22 +02001423static PyStatus
1424config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001425{
1426 /* More complex options configured by env var and -X option */
1427 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001428 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001429 || config_get_xoption(config, L"faulthandler")) {
1430 config->faulthandler = 1;
1431 }
1432 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001433 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001434 || config_get_xoption(config, L"importtime")) {
1435 config->import_time = 1;
1436 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001437
Pablo Galindoc5fc1562020-04-22 23:29:27 +01001438 if (config_get_env(config, "PYTHONOLDPARSER")
1439 || config_get_xoption(config, L"oldparser")) {
Victor Stinner1def7752020-04-23 03:03:24 +02001440 config->_use_peg_parser = 0;
Pablo Galindoc5fc1562020-04-22 23:29:27 +01001441 }
1442
Victor Stinner331a6a52019-05-27 16:39:22 +02001443 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001444 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001445 status = config_init_tracemalloc(config);
1446 if (_PyStatus_EXCEPTION(status)) {
1447 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001448 }
1449 }
1450
1451 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001452 status = config_init_pycache_prefix(config);
1453 if (_PyStatus_EXCEPTION(status)) {
1454 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001455 }
1456 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001457 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001458}
1459
1460
Victor Stinner709d23d2019-05-02 14:56:30 -04001461static const wchar_t *
Andy Lesteraa450a02020-03-07 11:36:04 -06001462config_get_stdio_errors(void)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001463{
1464#ifndef MS_WINDOWS
1465 const char *loc = setlocale(LC_CTYPE, NULL);
1466 if (loc != NULL) {
1467 /* surrogateescape is the default in the legacy C and POSIX locales */
1468 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001469 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001470 }
1471
1472#ifdef PY_COERCE_C_LOCALE
1473 /* surrogateescape is the default in locale coercion target locales */
1474 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001475 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001476 }
1477#endif
1478 }
1479
Victor Stinner709d23d2019-05-02 14:56:30 -04001480 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001481#else
1482 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001483 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001484#endif
1485}
1486
1487
Victor Stinner331a6a52019-05-27 16:39:22 +02001488static PyStatus
1489config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001490{
1491#ifdef MS_WINDOWS
1492 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001493 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001494 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001495#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001496 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001497#else
1498 const char *encoding = nl_langinfo(CODESET);
1499 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001500 return _PyStatus_ERR("failed to get the locale encoding: "
1501 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001502 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001503 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001504 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001505 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001506 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001507#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001508}
1509
1510
Victor Stinner331a6a52019-05-27 16:39:22 +02001511static PyStatus
1512config_init_stdio_encoding(PyConfig *config,
1513 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001514{
Victor Stinner331a6a52019-05-27 16:39:22 +02001515 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001516
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001517 /* If Py_SetStandardStreamEncoding() have been called, use these
1518 parameters. */
1519 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001520 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1521 _Py_StandardStreamEncoding,
1522 "_Py_StandardStreamEncoding");
1523 if (_PyStatus_EXCEPTION(status)) {
1524 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001525 }
1526 }
1527
1528 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001529 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1530 _Py_StandardStreamErrors,
1531 "_Py_StandardStreamErrors");
1532 if (_PyStatus_EXCEPTION(status)) {
1533 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001534 }
1535 }
1536
1537 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001538 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001539 }
1540
1541 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001542 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001543 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001544 char *pythonioencoding = _PyMem_RawStrdup(opt);
1545 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001546 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001547 }
1548
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001549 char *errors = strchr(pythonioencoding, ':');
1550 if (errors) {
1551 *errors = '\0';
1552 errors++;
1553 if (!errors[0]) {
1554 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001555 }
1556 }
1557
1558 /* Does PYTHONIOENCODING contain an encoding? */
1559 if (pythonioencoding[0]) {
1560 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001561 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1562 pythonioencoding,
1563 "PYTHONIOENCODING environment variable");
1564 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001565 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001566 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001567 }
1568 }
1569
1570 /* If the encoding is set but not the error handler,
1571 use "strict" error handler by default.
1572 PYTHONIOENCODING=latin1 behaves as
1573 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001574 if (!errors) {
1575 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001576 }
1577 }
1578
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001579 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001580 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1581 errors,
1582 "PYTHONIOENCODING environment variable");
1583 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001584 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001585 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001586 }
1587 }
1588
1589 PyMem_RawFree(pythonioencoding);
1590 }
1591
1592 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001593 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001594 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001595 status = PyConfig_SetString(config, &config->stdio_encoding,
1596 L"utf-8");
1597 if (_PyStatus_EXCEPTION(status)) {
1598 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001599 }
1600 }
1601 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001602 status = PyConfig_SetString(config, &config->stdio_errors,
1603 L"surrogateescape");
1604 if (_PyStatus_EXCEPTION(status)) {
1605 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001606 }
1607 }
1608 }
1609
1610 /* Choose the default error handler based on the current locale. */
1611 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001612 status = config_get_locale_encoding(config, &config->stdio_encoding);
1613 if (_PyStatus_EXCEPTION(status)) {
1614 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001615 }
1616 }
1617 if (config->stdio_errors == NULL) {
Andy Lesteraa450a02020-03-07 11:36:04 -06001618 const wchar_t *errors = config_get_stdio_errors();
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001619 assert(errors != NULL);
1620
Victor Stinner331a6a52019-05-27 16:39:22 +02001621 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1622 if (_PyStatus_EXCEPTION(status)) {
1623 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001624 }
1625 }
1626
Victor Stinner331a6a52019-05-27 16:39:22 +02001627 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001628}
1629
1630
Victor Stinner331a6a52019-05-27 16:39:22 +02001631static PyStatus
1632config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001633{
Victor Stinner331a6a52019-05-27 16:39:22 +02001634 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001635
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001636 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001637#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001638 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001639#else
Victor Stinnere2510952019-05-02 11:28:57 -04001640
1641#ifdef MS_WINDOWS
1642 if (preconfig->legacy_windows_fs_encoding) {
1643 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001644 status = PyConfig_SetString(config, &config->filesystem_encoding,
1645 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001646 }
1647 else
1648#endif
Victor Stinner20004952019-03-26 02:31:11 +01001649 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001650 status = PyConfig_SetString(config, &config->filesystem_encoding,
1651 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001652 }
Victor Stinnere2510952019-05-02 11:28:57 -04001653#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001654 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001655 status = PyConfig_SetString(config, &config->filesystem_encoding,
1656 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001657 }
Victor Stinnere2510952019-05-02 11:28:57 -04001658#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001659 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001660#ifdef MS_WINDOWS
1661 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001662 status = PyConfig_SetString(config, &config->filesystem_encoding,
1663 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001664#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001665 status = config_get_locale_encoding(config,
1666 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001667#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001668 }
Victor Stinnere2510952019-05-02 11:28:57 -04001669#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001670
Victor Stinner331a6a52019-05-27 16:39:22 +02001671 if (_PyStatus_EXCEPTION(status)) {
1672 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001673 }
1674 }
1675
1676 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001677 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001678#ifdef MS_WINDOWS
1679 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001680 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001681 }
1682 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001683 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001684 }
1685#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001686 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001687#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001688 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1689 if (_PyStatus_EXCEPTION(status)) {
1690 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001691 }
1692 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001693 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001694}
1695
1696
Victor Stinner331a6a52019-05-27 16:39:22 +02001697static PyStatus
1698config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001699{
Victor Stinner331a6a52019-05-27 16:39:22 +02001700 PyStatus status;
1701 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001702
Victor Stinner20004952019-03-26 02:31:11 +01001703 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001704 status = config_read_env_vars(config);
1705 if (_PyStatus_EXCEPTION(status)) {
1706 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001707 }
1708 }
1709
1710 /* -X options */
1711 if (config_get_xoption(config, L"showrefcount")) {
1712 config->show_ref_count = 1;
1713 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001714
Victor Stinner331a6a52019-05-27 16:39:22 +02001715 status = config_read_complex_options(config);
1716 if (_PyStatus_EXCEPTION(status)) {
1717 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001718 }
1719
Victor Stinner6c785c02018-08-01 17:56:14 +02001720 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001721 status = config_init_home(config);
1722 if (_PyStatus_EXCEPTION(status)) {
1723 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001724 }
1725 }
1726
Steve Dower177a41a2018-11-17 20:41:48 -08001727 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001728 status = config_init_executable(config);
1729 if (_PyStatus_EXCEPTION(status)) {
1730 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001731 }
1732 }
1733
Victor Stinner6c785c02018-08-01 17:56:14 +02001734 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001735 status = _PyConfig_InitPathConfig(config);
1736 if (_PyStatus_EXCEPTION(status)) {
1737 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001738 }
1739 }
1740
1741 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001742 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001743 if (config->faulthandler < 0) {
1744 config->faulthandler = 1;
1745 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001746 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001747 if (config->faulthandler < 0) {
1748 config->faulthandler = 0;
1749 }
1750 if (config->tracemalloc < 0) {
1751 config->tracemalloc = 0;
1752 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001753 if (config->use_hash_seed < 0) {
1754 config->use_hash_seed = 0;
1755 config->hash_seed = 0;
1756 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001757
Victor Stinner70fead22018-08-29 13:45:34 +02001758 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001759 status = config_init_fs_encoding(config, preconfig);
1760 if (_PyStatus_EXCEPTION(status)) {
1761 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001762 }
1763 }
1764
Victor Stinner331a6a52019-05-27 16:39:22 +02001765 status = config_init_stdio_encoding(config, preconfig);
1766 if (_PyStatus_EXCEPTION(status)) {
1767 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001768 }
1769
Victor Stinner62599762019-03-15 16:03:23 +01001770 if (config->argv.length < 1) {
1771 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001772 status = PyWideStringList_Append(&config->argv, L"");
1773 if (_PyStatus_EXCEPTION(status)) {
1774 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001775 }
1776 }
Victor Stinner870b0352019-05-17 03:15:12 +02001777
1778 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001779 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1780 L"default");
1781 if (_PyStatus_EXCEPTION(status)) {
1782 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001783 }
1784 }
1785
1786 if (config->configure_c_stdio < 0) {
1787 config->configure_c_stdio = 1;
1788 }
1789
Victor Stinner331a6a52019-05-27 16:39:22 +02001790 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001791}
Victor Stinner5ed69952018-11-06 15:59:52 +01001792
1793
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001794static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001795config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001796{
1797#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1798 /* don't translate newlines (\r\n <=> \n) */
1799 _setmode(fileno(stdin), O_BINARY);
1800 _setmode(fileno(stdout), O_BINARY);
1801 _setmode(fileno(stderr), O_BINARY);
1802#endif
1803
1804 if (!config->buffered_stdio) {
1805#ifdef HAVE_SETVBUF
1806 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1807 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1808 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1809#else /* !HAVE_SETVBUF */
1810 setbuf(stdin, (char *)NULL);
1811 setbuf(stdout, (char *)NULL);
1812 setbuf(stderr, (char *)NULL);
1813#endif /* !HAVE_SETVBUF */
1814 }
1815 else if (config->interactive) {
1816#ifdef MS_WINDOWS
1817 /* Doesn't have to have line-buffered -- use unbuffered */
1818 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1819 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1820#else /* !MS_WINDOWS */
1821#ifdef HAVE_SETVBUF
1822 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1823 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1824#endif /* HAVE_SETVBUF */
1825#endif /* !MS_WINDOWS */
1826 /* Leave stderr alone - it should be unbuffered anyway. */
1827 }
1828}
1829
1830
1831/* Write the configuration:
1832
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001833 - set Py_xxx global configuration variables
1834 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinnerdedaac02020-06-08 18:44:50 +02001835PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +02001836_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001837{
Victor Stinner331a6a52019-05-27 16:39:22 +02001838 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001839
1840 if (config->configure_c_stdio) {
1841 config_init_stdio(config);
1842 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001843
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001844 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001845 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001846 preconfig->isolated = config->isolated;
1847 preconfig->use_environment = config->use_environment;
1848 preconfig->dev_mode = config->dev_mode;
Victor Stinnerdedaac02020-06-08 18:44:50 +02001849
1850 if (_Py_SetArgcArgv(config->_orig_argv.length,
1851 config->_orig_argv.items) < 0)
1852 {
1853 return _PyStatus_NO_MEMORY();
1854 }
1855 return _PyStatus_OK();
Victor Stinner5ed69952018-11-06 15:59:52 +01001856}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001857
1858
Victor Stinner331a6a52019-05-27 16:39:22 +02001859/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001860
1861static void
Victor Stinner2f549082019-03-29 15:13:46 +01001862config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001863{
Victor Stinner2f549082019-03-29 15:13:46 +01001864 FILE *f = error ? stderr : stdout;
1865
1866 fprintf(f, usage_line, program);
1867 if (error)
1868 fprintf(f, "Try `python -h' for more information.\n");
1869 else {
1870 fputs(usage_1, f);
1871 fputs(usage_2, f);
1872 fputs(usage_3, f);
1873 fprintf(f, usage_4, (wint_t)DELIM);
1874 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1875 fputs(usage_6, f);
1876 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001877}
1878
1879
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001880/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001881static PyStatus
1882config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001883 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001884{
Victor Stinner331a6a52019-05-27 16:39:22 +02001885 PyStatus status;
1886 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001887 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001888 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001889
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001890 _PyOS_ResetGetOpt();
1891 do {
1892 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001893 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001894 if (c == EOF) {
1895 break;
1896 }
1897
1898 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001899 if (config->run_command == NULL) {
1900 /* -c is the last option; following arguments
1901 that look like options are left for the
1902 command to interpret. */
1903 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1904 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1905 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001906 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001907 }
1908 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1909 command[len - 2] = '\n';
1910 command[len - 1] = 0;
1911 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001912 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001913 break;
1914 }
1915
1916 if (c == 'm') {
1917 /* -m is the last option; following arguments
1918 that look like options are left for the
1919 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001920 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001921 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1922 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001923 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001924 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001925 }
1926 break;
1927 }
1928
1929 switch (c) {
1930 case 0:
1931 // Handle long option.
1932 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001933 if (wcscmp(_PyOS_optarg, L"always") == 0
1934 || wcscmp(_PyOS_optarg, L"never") == 0
1935 || wcscmp(_PyOS_optarg, L"default") == 0)
1936 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001937 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1938 _PyOS_optarg);
1939 if (_PyStatus_EXCEPTION(status)) {
1940 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001941 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001942 } else {
1943 fprintf(stderr, "--check-hash-based-pycs must be one of "
1944 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001945 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001946 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001947 }
1948 break;
1949
1950 case 'b':
1951 config->bytes_warning++;
1952 break;
1953
1954 case 'd':
1955 config->parser_debug++;
1956 break;
1957
1958 case 'i':
1959 config->inspect++;
1960 config->interactive++;
1961 break;
1962
Victor Stinner6dcb5422019-03-05 02:44:12 +01001963 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001964 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001965 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001966 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001967 break;
1968
1969 /* case 'J': reserved for Jython */
1970
1971 case 'O':
1972 config->optimization_level++;
1973 break;
1974
1975 case 'B':
1976 config->write_bytecode = 0;
1977 break;
1978
1979 case 's':
1980 config->user_site_directory = 0;
1981 break;
1982
1983 case 'S':
1984 config->site_import = 0;
1985 break;
1986
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001987 case 't':
1988 /* ignored for backwards compatibility */
1989 break;
1990
1991 case 'u':
1992 config->buffered_stdio = 0;
1993 break;
1994
1995 case 'v':
1996 config->verbose++;
1997 break;
1998
1999 case 'x':
2000 config->skip_source_first_line = 1;
2001 break;
2002
2003 case 'h':
2004 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02002005 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002006 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002007
2008 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01002009 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002010 break;
2011
2012 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002013 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2014 if (_PyStatus_EXCEPTION(status)) {
2015 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002016 }
2017 break;
2018
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002019 case 'q':
2020 config->quiet++;
2021 break;
2022
2023 case 'R':
2024 config->use_hash_seed = 0;
2025 break;
2026
2027 /* This space reserved for other options */
2028
2029 default:
2030 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002031 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002032 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002033 }
2034 } while (1);
2035
Victor Stinner2f549082019-03-29 15:13:46 +01002036 if (print_version) {
2037 printf("Python %s\n",
2038 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002039 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002040 }
2041
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002042 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002043 && _PyOS_optind < argv->length
2044 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002045 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002046 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002047 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002048 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002049 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002050 }
2051 }
2052
2053 if (config->run_command != NULL || config->run_module != NULL) {
2054 /* Backup _PyOS_optind */
2055 _PyOS_optind--;
2056 }
2057
Victor Stinnerae239f62019-05-16 17:02:56 +02002058 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002059
Victor Stinner331a6a52019-05-27 16:39:22 +02002060 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002061}
2062
2063
2064#ifdef MS_WINDOWS
2065# define WCSTOK wcstok_s
2066#else
2067# define WCSTOK wcstok
2068#endif
2069
2070/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002071static PyStatus
2072config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002073{
Victor Stinner331a6a52019-05-27 16:39:22 +02002074 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002075 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2076 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002077 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002078 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002079 if (_PyStatus_EXCEPTION(status)) {
2080 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002081 }
2082
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002083 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002084 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002085 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002086 }
2087
2088
2089 wchar_t *warning, *context = NULL;
2090 for (warning = WCSTOK(env, L",", &context);
2091 warning != NULL;
2092 warning = WCSTOK(NULL, L",", &context))
2093 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002094 status = PyWideStringList_Append(warnoptions, warning);
2095 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002096 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002097 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002098 }
2099 }
2100 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002101 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002102}
2103
2104
Victor Stinner331a6a52019-05-27 16:39:22 +02002105static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002106warnoptions_append(PyConfig *config, PyWideStringList *options,
2107 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002108{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002109 /* config_init_warnoptions() add existing config warnoptions at the end:
2110 ensure that the new option is not already present in this list to
2111 prevent change the options order whne config_init_warnoptions() is
2112 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002113 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002114 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002115 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002116 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002117 if (_PyWideStringList_Find(options, option)) {
2118 /* Already present: do nothing */
2119 return _PyStatus_OK();
2120 }
2121 return PyWideStringList_Append(options, option);
2122}
2123
2124
2125static PyStatus
2126warnoptions_extend(PyConfig *config, PyWideStringList *options,
2127 const PyWideStringList *options2)
2128{
2129 const Py_ssize_t len = options2->length;
2130 wchar_t *const *items = options2->items;
2131
2132 for (Py_ssize_t i = 0; i < len; i++) {
2133 PyStatus status = warnoptions_append(config, options, items[i]);
2134 if (_PyStatus_EXCEPTION(status)) {
2135 return status;
2136 }
2137 }
2138 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002139}
2140
2141
Victor Stinner331a6a52019-05-27 16:39:22 +02002142static PyStatus
2143config_init_warnoptions(PyConfig *config,
2144 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002145 const PyWideStringList *env_warnoptions,
2146 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002147{
Victor Stinner331a6a52019-05-27 16:39:22 +02002148 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002149 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002150
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002151 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002152 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002153 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002154 * - PyConfig.dev_mode: "default" filter
2155 * - PYTHONWARNINGS environment variable
2156 * - '-W' command line options
2157 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2158 * "default::BytesWarning" or "error::BytesWarning" filter
2159 * - early PySys_AddWarnOption() calls
2160 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002161 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002162 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2163 * module works on the basis of "the most recently added filter will be
2164 * checked first", we add the lowest precedence entries first so that later
2165 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002166 */
2167
Victor Stinner20004952019-03-26 02:31:11 +01002168 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002169 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002170 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002171 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002172 }
2173 }
2174
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002175 status = warnoptions_extend(config, &options, env_warnoptions);
2176 if (_PyStatus_EXCEPTION(status)) {
2177 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002178 }
2179
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002180 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2181 if (_PyStatus_EXCEPTION(status)) {
2182 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002183 }
2184
2185 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2186 * don't even try to emit a warning, so we skip setting the filter in that
2187 * case.
2188 */
2189 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002190 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002191 if (config->bytes_warning> 1) {
2192 filter = L"error::BytesWarning";
2193 }
2194 else {
2195 filter = L"default::BytesWarning";
2196 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002197 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002198 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002199 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002200 }
2201 }
Victor Stinner120b7072019-08-23 18:03:08 +01002202
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002203 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002204 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002205 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002206 }
2207
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002208 /* Always add all PyConfig.warnoptions options */
2209 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2210 if (_PyStatus_EXCEPTION(status)) {
2211 goto error;
2212 }
2213
2214 _PyWideStringList_Clear(&config->warnoptions);
2215 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002216 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002217
2218error:
2219 _PyWideStringList_Clear(&options);
2220 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002221}
2222
2223
Victor Stinner331a6a52019-05-27 16:39:22 +02002224static PyStatus
2225config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002226{
Victor Stinner331a6a52019-05-27 16:39:22 +02002227 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002228 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002229
Victor Stinner74f65682019-03-15 15:08:05 +01002230 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002231 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002232 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002233 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2234 if (_PyStatus_EXCEPTION(status)) {
2235 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002236 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002237 }
2238 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002239 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002240 slice.length = cmdline_argv->length - opt_index;
2241 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002242 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2243 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002244 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002245 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002246 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002247
2248 wchar_t *arg0 = NULL;
2249 if (config->run_command != NULL) {
2250 /* Force sys.argv[0] = '-c' */
2251 arg0 = L"-c";
2252 }
2253 else if (config->run_module != NULL) {
2254 /* Force sys.argv[0] = '-m'*/
2255 arg0 = L"-m";
2256 }
Victor Stinner3939c322019-06-25 15:02:43 +02002257
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002258 if (arg0 != NULL) {
2259 arg0 = _PyMem_RawWcsdup(arg0);
2260 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002261 _PyWideStringList_Clear(&config_argv);
2262 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002263 }
2264
Victor Stinnerfa153762019-03-20 04:25:38 +01002265 PyMem_RawFree(config_argv.items[0]);
2266 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002267 }
2268
Victor Stinner331a6a52019-05-27 16:39:22 +02002269 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002270 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002271 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002272}
2273
2274
Victor Stinner331a6a52019-05-27 16:39:22 +02002275static PyStatus
2276core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002277{
Victor Stinner331a6a52019-05-27 16:39:22 +02002278 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002279
Victor Stinnercab5d072019-05-17 19:01:14 +02002280 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002281 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2282 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002283 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002284 }
2285
Victor Stinner331a6a52019-05-27 16:39:22 +02002286 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002287
2288 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2289 if (_PyStatus_EXCEPTION(status)) {
2290 return status;
2291 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002292
Victor Stinner331a6a52019-05-27 16:39:22 +02002293 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002294
Victor Stinner331a6a52019-05-27 16:39:22 +02002295 status = _PyPreCmdline_Read(precmdline, &preconfig);
2296 if (_PyStatus_EXCEPTION(status)) {
2297 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002298 }
2299
Victor Stinner331a6a52019-05-27 16:39:22 +02002300 status = _PyPreCmdline_SetConfig(precmdline, config);
2301 if (_PyStatus_EXCEPTION(status)) {
2302 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002303 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002304 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002305}
2306
2307
Victor Stinner3939c322019-06-25 15:02:43 +02002308/* Get run_filename absolute path */
2309static PyStatus
2310config_run_filename_abspath(PyConfig *config)
2311{
2312 if (!config->run_filename) {
2313 return _PyStatus_OK();
2314 }
2315
2316#ifndef MS_WINDOWS
2317 if (_Py_isabs(config->run_filename)) {
2318 /* path is already absolute */
2319 return _PyStatus_OK();
2320 }
2321#endif
2322
2323 wchar_t *abs_filename;
2324 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2325 /* failed to get the absolute path of the command line filename:
2326 ignore the error, keep the relative path */
2327 return _PyStatus_OK();
2328 }
2329 if (abs_filename == NULL) {
2330 return _PyStatus_NO_MEMORY();
2331 }
2332
2333 PyMem_RawFree(config->run_filename);
2334 config->run_filename = abs_filename;
2335 return _PyStatus_OK();
2336}
2337
2338
Victor Stinner331a6a52019-05-27 16:39:22 +02002339static PyStatus
2340config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002341{
Victor Stinner331a6a52019-05-27 16:39:22 +02002342 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002343 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2344 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2345 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002346
Victor Stinnerae239f62019-05-16 17:02:56 +02002347 if (config->parse_argv < 0) {
2348 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002349 }
Victor Stinner870b0352019-05-17 03:15:12 +02002350
Victor Stinnerfed02e12019-05-17 11:12:09 +02002351 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002352 status = config_init_program_name(config);
2353 if (_PyStatus_EXCEPTION(status)) {
2354 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002355 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002356 }
Victor Stinner2f549082019-03-29 15:13:46 +01002357
Victor Stinnerae239f62019-05-16 17:02:56 +02002358 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002359 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002360 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2361 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002362 goto done;
2363 }
2364
Victor Stinner3939c322019-06-25 15:02:43 +02002365 status = config_run_filename_abspath(config);
2366 if (_PyStatus_EXCEPTION(status)) {
2367 goto done;
2368 }
2369
Victor Stinner331a6a52019-05-27 16:39:22 +02002370 status = config_update_argv(config, opt_index);
2371 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002372 goto done;
2373 }
Victor Stinner2f549082019-03-29 15:13:46 +01002374 }
Victor Stinner3939c322019-06-25 15:02:43 +02002375 else {
2376 status = config_run_filename_abspath(config);
2377 if (_PyStatus_EXCEPTION(status)) {
2378 goto done;
2379 }
2380 }
Victor Stinner2f549082019-03-29 15:13:46 +01002381
Victor Stinner2f549082019-03-29 15:13:46 +01002382 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002383 status = config_init_env_warnoptions(config, &env_warnoptions);
2384 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002385 goto done;
2386 }
2387 }
2388
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002389 /* Handle early PySys_AddWarnOption() calls */
2390 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2391 if (_PyStatus_EXCEPTION(status)) {
2392 goto done;
2393 }
2394
Victor Stinner331a6a52019-05-27 16:39:22 +02002395 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002396 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002397 &env_warnoptions,
2398 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002399 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002400 goto done;
2401 }
2402
Victor Stinner331a6a52019-05-27 16:39:22 +02002403 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002404
2405done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002406 _PyWideStringList_Clear(&cmdline_warnoptions);
2407 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002408 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002409 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002410}
2411
2412
Victor Stinner331a6a52019-05-27 16:39:22 +02002413PyStatus
2414_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002415{
Victor Stinner331a6a52019-05-27 16:39:22 +02002416 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2417 if (_PyStatus_EXCEPTION(status)) {
2418 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002419 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002420
Victor Stinner5f38b842019-05-01 02:30:12 +02002421 return _PyArgv_AsWstrList(args, &config->argv);
2422}
2423
2424
Victor Stinner70005ac2019-05-02 15:25:34 -04002425/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2426 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002427PyStatus
2428PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002429{
2430 _PyArgv args = {
2431 .argc = argc,
2432 .use_bytes_argv = 1,
2433 .bytes_argv = argv,
2434 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002435 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002436}
2437
2438
Victor Stinner331a6a52019-05-27 16:39:22 +02002439PyStatus
2440PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002441{
2442 _PyArgv args = {
2443 .argc = argc,
2444 .use_bytes_argv = 0,
2445 .bytes_argv = NULL,
2446 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002447 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002448}
2449
2450
Victor Stinner36242fd2019-07-01 19:13:50 +02002451PyStatus
2452PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2453 Py_ssize_t length, wchar_t **items)
2454{
2455 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2456 if (_PyStatus_EXCEPTION(status)) {
2457 return status;
2458 }
2459
2460 PyWideStringList list2 = {.length = length, .items = items};
2461 if (_PyWideStringList_Copy(list, &list2) < 0) {
2462 return _PyStatus_NO_MEMORY();
2463 }
2464 return _PyStatus_OK();
2465}
2466
2467
Victor Stinner331a6a52019-05-27 16:39:22 +02002468/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002469
2470 * Command line arguments
2471 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002472 * Py_xxx global configuration variables
2473
2474 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002475PyStatus
2476PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002477{
Victor Stinner331a6a52019-05-27 16:39:22 +02002478 PyStatus status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002479
Victor Stinner331a6a52019-05-27 16:39:22 +02002480 status = _Py_PreInitializeFromConfig(config, NULL);
2481 if (_PyStatus_EXCEPTION(status)) {
2482 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002483 }
2484
Victor Stinner331a6a52019-05-27 16:39:22 +02002485 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002486
Victor Stinnerdedaac02020-06-08 18:44:50 +02002487 if (config->_orig_argv.length == 0
2488 && !(config->argv.length == 1
2489 && wcscmp(config->argv.items[0], L"") == 0))
2490 {
2491 if (_PyWideStringList_Copy(&config->_orig_argv, &config->argv) < 0) {
2492 return _PyStatus_NO_MEMORY();
2493 }
Victor Stinnercab5d072019-05-17 19:01:14 +02002494 }
2495
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002496 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002497 status = core_read_precmdline(config, &precmdline);
2498 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002499 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002500 }
2501
Victor Stinner870b0352019-05-17 03:15:12 +02002502 assert(config->isolated >= 0);
2503 if (config->isolated) {
2504 config->use_environment = 0;
2505 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002506 }
2507
Victor Stinner331a6a52019-05-27 16:39:22 +02002508 status = config_read_cmdline(config);
2509 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002510 goto done;
2511 }
2512
Victor Stinner120b7072019-08-23 18:03:08 +01002513 /* Handle early PySys_AddXOption() calls */
2514 status = _PySys_ReadPreinitXOptions(config);
2515 if (_PyStatus_EXCEPTION(status)) {
2516 goto done;
2517 }
2518
Victor Stinner331a6a52019-05-27 16:39:22 +02002519 status = config_read(config);
2520 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002521 goto done;
2522 }
2523
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002524 /* Check config consistency */
2525 assert(config->isolated >= 0);
2526 assert(config->use_environment >= 0);
2527 assert(config->dev_mode >= 0);
Victor Stinner1def7752020-04-23 03:03:24 +02002528 assert(config->_use_peg_parser >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002529 assert(config->install_signal_handlers >= 0);
2530 assert(config->use_hash_seed >= 0);
2531 assert(config->faulthandler >= 0);
2532 assert(config->tracemalloc >= 0);
2533 assert(config->site_import >= 0);
2534 assert(config->bytes_warning >= 0);
2535 assert(config->inspect >= 0);
2536 assert(config->interactive >= 0);
2537 assert(config->optimization_level >= 0);
2538 assert(config->parser_debug >= 0);
2539 assert(config->write_bytecode >= 0);
2540 assert(config->verbose >= 0);
2541 assert(config->quiet >= 0);
2542 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002543 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002544 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002545 assert(config->buffered_stdio >= 0);
2546 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002547 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002548 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2549 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002550 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2551 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2552 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002553 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002554 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002555 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002556 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002557 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002558 assert(config->prefix != NULL);
2559 assert(config->base_prefix != NULL);
2560 assert(config->exec_prefix != NULL);
2561 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002562 }
2563 assert(config->filesystem_encoding != NULL);
2564 assert(config->filesystem_errors != NULL);
2565 assert(config->stdio_encoding != NULL);
2566 assert(config->stdio_errors != NULL);
2567#ifdef MS_WINDOWS
2568 assert(config->legacy_windows_stdio >= 0);
2569#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002570 /* -c and -m options are exclusive */
2571 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002572 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002573 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002574 assert(config->pathconfig_warnings >= 0);
Victor Stinnerdedaac02020-06-08 18:44:50 +02002575 assert(_PyWideStringList_CheckConsistency(&config->_orig_argv));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002576
Victor Stinner331a6a52019-05-27 16:39:22 +02002577 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002578
2579done:
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002580 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002581 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002582}
Victor Stinner1075d162019-03-25 23:19:57 +01002583
2584
2585PyObject*
2586_Py_GetConfigsAsDict(void)
2587{
Victor Stinner331a6a52019-05-27 16:39:22 +02002588 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002589 PyObject *dict = NULL;
2590
Victor Stinner331a6a52019-05-27 16:39:22 +02002591 result = PyDict_New();
2592 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002593 goto error;
2594 }
2595
Victor Stinner331a6a52019-05-27 16:39:22 +02002596 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002597 dict = _Py_GetGlobalVariablesAsDict();
2598 if (dict == NULL) {
2599 goto error;
2600 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002601 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002602 goto error;
2603 }
2604 Py_CLEAR(dict);
2605
2606 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002607 PyThreadState *tstate = _PyThreadState_GET();
2608 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002609 dict = _PyPreConfig_AsDict(pre_config);
2610 if (dict == NULL) {
2611 goto error;
2612 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002613 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002614 goto error;
2615 }
2616 Py_CLEAR(dict);
2617
2618 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002619 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinner331a6a52019-05-27 16:39:22 +02002620 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002621 if (dict == NULL) {
2622 goto error;
2623 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002624 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002625 goto error;
2626 }
2627 Py_CLEAR(dict);
2628
Victor Stinner331a6a52019-05-27 16:39:22 +02002629 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002630
2631error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002632 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002633 Py_XDECREF(dict);
2634 return NULL;
2635}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002636
2637
2638static void
2639init_dump_ascii_wstr(const wchar_t *str)
2640{
2641 if (str == NULL) {
2642 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002643 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002644 }
2645
2646 PySys_WriteStderr("'");
2647 for (; *str != L'\0'; str++) {
2648 wchar_t ch = *str;
2649 if (ch == L'\'') {
2650 PySys_WriteStderr("\\'");
2651 } else if (0x20 <= ch && ch < 0x7f) {
2652 PySys_WriteStderr("%lc", ch);
2653 }
2654 else if (ch <= 0xff) {
2655 PySys_WriteStderr("\\x%02x", ch);
2656 }
2657#if SIZEOF_WCHAR_T > 2
2658 else if (ch > 0xffff) {
2659 PySys_WriteStderr("\\U%08x", ch);
2660 }
2661#endif
2662 else {
2663 PySys_WriteStderr("\\u%04x", ch);
2664 }
2665 }
2666 PySys_WriteStderr("'");
2667}
2668
2669
2670/* Dump the Python path configuration into sys.stderr */
2671void
2672_Py_DumpPathConfig(PyThreadState *tstate)
2673{
2674 PyObject *exc_type, *exc_value, *exc_tb;
2675 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2676
2677 PySys_WriteStderr("Python path configuration:\n");
2678
2679#define DUMP_CONFIG(NAME, FIELD) \
2680 do { \
2681 PySys_WriteStderr(" " NAME " = "); \
2682 init_dump_ascii_wstr(config->FIELD); \
2683 PySys_WriteStderr("\n"); \
2684 } while (0)
2685
Victor Stinnerda7933e2020-04-13 03:04:28 +02002686 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002687 DUMP_CONFIG("PYTHONHOME", home);
2688 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2689 DUMP_CONFIG("program name", program_name);
2690 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2691 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2692 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2693 PySys_WriteStderr(" import site = %i\n", config->site_import);
2694#undef DUMP_CONFIG
2695
2696#define DUMP_SYS(NAME) \
2697 do { \
2698 obj = PySys_GetObject(#NAME); \
2699 PySys_FormatStderr(" sys.%s = ", #NAME); \
2700 if (obj != NULL) { \
2701 PySys_FormatStderr("%A", obj); \
2702 } \
2703 else { \
2704 PySys_WriteStderr("(not set)"); \
2705 } \
2706 PySys_FormatStderr("\n"); \
2707 } while (0)
2708
2709 PyObject *obj;
2710 DUMP_SYS(_base_executable);
2711 DUMP_SYS(base_prefix);
2712 DUMP_SYS(base_exec_prefix);
2713 DUMP_SYS(executable);
2714 DUMP_SYS(prefix);
2715 DUMP_SYS(exec_prefix);
2716#undef DUMP_SYS
2717
2718 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2719 if (sys_path != NULL && PyList_Check(sys_path)) {
2720 PySys_WriteStderr(" sys.path = [\n");
2721 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2722 for (Py_ssize_t i=0; i < len; i++) {
2723 PyObject *path = PyList_GET_ITEM(sys_path, i);
2724 PySys_FormatStderr(" %A,\n", path);
2725 }
2726 PySys_WriteStderr(" ]\n");
2727 }
2728
2729 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2730}