blob: 58cca562f336dc2845d1bdb5695ea74b684d97ac [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
546/* Make the *original* argc/argv available to other modules.
547 This is rare, but it is needed by the secureware extension. */
548void
549Py_GetArgcArgv(int *argc, wchar_t ***argv)
550{
Victor Stinner74f65682019-03-15 15:08:05 +0100551 *argc = (int)orig_argv.length;
552 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100553}
554
555
Victor Stinner331a6a52019-05-27 16:39:22 +0200556/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100557
558#define DECODE_LOCALE_ERR(NAME, LEN) \
559 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200560 ? _PyStatus_ERR("cannot decode " NAME) \
561 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100562
Victor Stinner441b10c2019-09-28 04:28:35 +0200563
Victor Stinner6c785c02018-08-01 17:56:14 +0200564/* Free memory allocated in config, but don't clear all attributes */
565void
Victor Stinner331a6a52019-05-27 16:39:22 +0200566PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200567{
568#define CLEAR(ATTR) \
569 do { \
570 PyMem_RawFree(ATTR); \
571 ATTR = NULL; \
572 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200573
574 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200575 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200576 CLEAR(config->home);
577 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200578
Victor Stinner331a6a52019-05-27 16:39:22 +0200579 _PyWideStringList_Clear(&config->argv);
580 _PyWideStringList_Clear(&config->warnoptions);
581 _PyWideStringList_Clear(&config->xoptions);
582 _PyWideStringList_Clear(&config->module_search_paths);
583 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200584
585 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700586 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200587 CLEAR(config->prefix);
588 CLEAR(config->base_prefix);
589 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200590 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200591
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200592 CLEAR(config->filesystem_encoding);
593 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200594 CLEAR(config->stdio_encoding);
595 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100596 CLEAR(config->run_command);
597 CLEAR(config->run_module);
598 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400599 CLEAR(config->check_hash_pycs_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200600#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200601}
602
603
Victor Stinner8462a492019-10-01 12:06:16 +0200604void
Victor Stinner331a6a52019-05-27 16:39:22 +0200605_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200606{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200607 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200608
Victor Stinner022be022019-05-22 23:58:50 +0200609 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200610 config->isolated = -1;
611 config->use_environment = -1;
612 config->dev_mode = -1;
613 config->install_signal_handlers = 1;
614 config->use_hash_seed = -1;
615 config->faulthandler = -1;
616 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200617 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200618 config->parse_argv = 0;
619 config->site_import = -1;
620 config->bytes_warning = -1;
621 config->inspect = -1;
622 config->interactive = -1;
623 config->optimization_level = -1;
624 config->parser_debug= -1;
625 config->write_bytecode = -1;
626 config->verbose = -1;
627 config->quiet = -1;
628 config->user_site_directory = -1;
629 config->configure_c_stdio = 0;
630 config->buffered_stdio = -1;
631 config->_install_importlib = 1;
632 config->check_hash_pycs_mode = NULL;
633 config->pathconfig_warnings = -1;
634 config->_init_main = 1;
635#ifdef MS_WINDOWS
636 config->legacy_windows_stdio = -1;
637#endif
Victor Stinner1def7752020-04-23 03:03:24 +0200638 config->_use_peg_parser = 1;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200639}
640
641
Victor Stinner8462a492019-10-01 12:06:16 +0200642static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200643config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200644{
Victor Stinner8462a492019-10-01 12:06:16 +0200645 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200646
647 config->isolated = 0;
648 config->use_environment = 1;
649 config->site_import = 1;
650 config->bytes_warning = 0;
651 config->inspect = 0;
652 config->interactive = 0;
653 config->optimization_level = 0;
654 config->parser_debug= 0;
655 config->write_bytecode = 1;
656 config->verbose = 0;
657 config->quiet = 0;
658 config->user_site_directory = 1;
659 config->buffered_stdio = 1;
660 config->pathconfig_warnings = 1;
661#ifdef MS_WINDOWS
662 config->legacy_windows_stdio = 0;
663#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200664}
665
666
Victor Stinner8462a492019-10-01 12:06:16 +0200667void
Victor Stinner331a6a52019-05-27 16:39:22 +0200668PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200669{
Victor Stinner8462a492019-10-01 12:06:16 +0200670 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200671
Victor Stinner022be022019-05-22 23:58:50 +0200672 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200673 config->configure_c_stdio = 1;
674 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200675}
676
677
Victor Stinner8462a492019-10-01 12:06:16 +0200678void
Victor Stinner331a6a52019-05-27 16:39:22 +0200679PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200680{
Victor Stinner8462a492019-10-01 12:06:16 +0200681 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200682
Victor Stinner022be022019-05-22 23:58:50 +0200683 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200684 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200685 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200686 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200687 config->dev_mode = 0;
688 config->install_signal_handlers = 0;
689 config->use_hash_seed = 0;
690 config->faulthandler = 0;
691 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200692 config->pathconfig_warnings = 0;
693#ifdef MS_WINDOWS
694 config->legacy_windows_stdio = 0;
695#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200696}
697
698
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200699/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200700PyStatus
701PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200702{
Victor Stinner331a6a52019-05-27 16:39:22 +0200703 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
704 if (_PyStatus_EXCEPTION(status)) {
705 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200706 }
707
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200708 wchar_t *str2;
709 if (str != NULL) {
710 str2 = _PyMem_RawWcsdup(str);
711 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200712 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200713 }
714 }
715 else {
716 str2 = NULL;
717 }
718 PyMem_RawFree(*config_str);
719 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200720 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200721}
722
723
Victor Stinner331a6a52019-05-27 16:39:22 +0200724static PyStatus
725config_set_bytes_string(PyConfig *config, wchar_t **config_str,
726 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200727{
Victor Stinner331a6a52019-05-27 16:39:22 +0200728 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
729 if (_PyStatus_EXCEPTION(status)) {
730 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400731 }
732
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200733 wchar_t *str2;
734 if (str != NULL) {
735 size_t len;
736 str2 = Py_DecodeLocale(str, &len);
737 if (str2 == NULL) {
738 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200739 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200740 }
741 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200742 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200743 }
744 }
745 }
746 else {
747 str2 = NULL;
748 }
749 PyMem_RawFree(*config_str);
750 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200751 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200752}
753
754
Victor Stinner331a6a52019-05-27 16:39:22 +0200755#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
756 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400757
758
Victor Stinner70005ac2019-05-02 15:25:34 -0400759/* Decode str using Py_DecodeLocale() and set the result into *config_str.
760 Pre-initialize Python if needed to ensure that encodings are properly
761 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200762PyStatus
763PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200764 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400765{
Victor Stinner331a6a52019-05-27 16:39:22 +0200766 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400767}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200768
769
Victor Stinner331a6a52019-05-27 16:39:22 +0200770PyStatus
771_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200772{
Victor Stinner331a6a52019-05-27 16:39:22 +0200773 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200774
Victor Stinner331a6a52019-05-27 16:39:22 +0200775 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200776
777#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200778#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200779 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200780 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
781 if (_PyStatus_EXCEPTION(status)) { \
782 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200783 } \
784 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100785#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200786 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200787 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200788 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200789 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200790 } while (0)
791
Victor Stinner6d1c4672019-05-20 11:02:00 +0200792 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100793 COPY_ATTR(isolated);
794 COPY_ATTR(use_environment);
795 COPY_ATTR(dev_mode);
Victor Stinner1def7752020-04-23 03:03:24 +0200796 COPY_ATTR(_use_peg_parser);
Victor Stinner6c785c02018-08-01 17:56:14 +0200797 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200798 COPY_ATTR(use_hash_seed);
799 COPY_ATTR(hash_seed);
800 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200801 COPY_ATTR(faulthandler);
802 COPY_ATTR(tracemalloc);
803 COPY_ATTR(import_time);
804 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200805 COPY_ATTR(dump_refs);
806 COPY_ATTR(malloc_stats);
807
Victor Stinner124b9eb2018-08-29 01:29:06 +0200808 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200809 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200810 COPY_WSTR_ATTR(home);
811 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200812
Victor Stinnerae239f62019-05-16 17:02:56 +0200813 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100814 COPY_WSTRLIST(argv);
815 COPY_WSTRLIST(warnoptions);
816 COPY_WSTRLIST(xoptions);
817 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200818 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200819
Victor Stinner124b9eb2018-08-29 01:29:06 +0200820 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700821 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200822 COPY_WSTR_ATTR(prefix);
823 COPY_WSTR_ATTR(base_prefix);
824 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200825 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200826
Victor Stinner6c785c02018-08-01 17:56:14 +0200827 COPY_ATTR(site_import);
828 COPY_ATTR(bytes_warning);
829 COPY_ATTR(inspect);
830 COPY_ATTR(interactive);
831 COPY_ATTR(optimization_level);
832 COPY_ATTR(parser_debug);
833 COPY_ATTR(write_bytecode);
834 COPY_ATTR(verbose);
835 COPY_ATTR(quiet);
836 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200837 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200838 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400839 COPY_WSTR_ATTR(filesystem_encoding);
840 COPY_WSTR_ATTR(filesystem_errors);
841 COPY_WSTR_ATTR(stdio_encoding);
842 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200843#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200844 COPY_ATTR(legacy_windows_stdio);
845#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100846 COPY_ATTR(skip_source_first_line);
847 COPY_WSTR_ATTR(run_command);
848 COPY_WSTR_ATTR(run_module);
849 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400850 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200851 COPY_ATTR(pathconfig_warnings);
852 COPY_ATTR(_init_main);
Victor Stinner6c785c02018-08-01 17:56:14 +0200853
854#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200855#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200856#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200857 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200858}
859
860
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100861static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200862config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100863{
864 PyObject *dict;
865
866 dict = PyDict_New();
867 if (dict == NULL) {
868 return NULL;
869 }
870
871#define SET_ITEM(KEY, EXPR) \
872 do { \
873 PyObject *obj = (EXPR); \
874 if (obj == NULL) { \
875 goto fail; \
876 } \
877 int res = PyDict_SetItemString(dict, (KEY), obj); \
878 Py_DECREF(obj); \
879 if (res < 0) { \
880 goto fail; \
881 } \
882 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100883#define SET_ITEM_INT(ATTR) \
884 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
885#define SET_ITEM_UINT(ATTR) \
886 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100887#define FROM_WSTRING(STR) \
888 ((STR != NULL) ? \
889 PyUnicode_FromWideChar(STR, -1) \
890 : (Py_INCREF(Py_None), Py_None))
891#define SET_ITEM_WSTR(ATTR) \
892 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
893#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200894 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100895
Victor Stinner6d1c4672019-05-20 11:02:00 +0200896 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100897 SET_ITEM_INT(isolated);
898 SET_ITEM_INT(use_environment);
899 SET_ITEM_INT(dev_mode);
Victor Stinner1def7752020-04-23 03:03:24 +0200900 SET_ITEM_INT(_use_peg_parser);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100901 SET_ITEM_INT(install_signal_handlers);
902 SET_ITEM_INT(use_hash_seed);
903 SET_ITEM_UINT(hash_seed);
904 SET_ITEM_INT(faulthandler);
905 SET_ITEM_INT(tracemalloc);
906 SET_ITEM_INT(import_time);
907 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100908 SET_ITEM_INT(dump_refs);
909 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400910 SET_ITEM_WSTR(filesystem_encoding);
911 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100912 SET_ITEM_WSTR(pycache_prefix);
913 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200914 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100915 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100916 SET_ITEM_WSTRLIST(xoptions);
917 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200918 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100919 SET_ITEM_WSTR(home);
920 SET_ITEM_WSTRLIST(module_search_paths);
921 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700922 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100923 SET_ITEM_WSTR(prefix);
924 SET_ITEM_WSTR(base_prefix);
925 SET_ITEM_WSTR(exec_prefix);
926 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100927 SET_ITEM_INT(site_import);
928 SET_ITEM_INT(bytes_warning);
929 SET_ITEM_INT(inspect);
930 SET_ITEM_INT(interactive);
931 SET_ITEM_INT(optimization_level);
932 SET_ITEM_INT(parser_debug);
933 SET_ITEM_INT(write_bytecode);
934 SET_ITEM_INT(verbose);
935 SET_ITEM_INT(quiet);
936 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200937 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100938 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400939 SET_ITEM_WSTR(stdio_encoding);
940 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100941#ifdef MS_WINDOWS
942 SET_ITEM_INT(legacy_windows_stdio);
943#endif
944 SET_ITEM_INT(skip_source_first_line);
945 SET_ITEM_WSTR(run_command);
946 SET_ITEM_WSTR(run_module);
947 SET_ITEM_WSTR(run_filename);
948 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400949 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200950 SET_ITEM_INT(pathconfig_warnings);
951 SET_ITEM_INT(_init_main);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100952
953 return dict;
954
955fail:
956 Py_DECREF(dict);
957 return NULL;
958
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100959#undef FROM_WSTRING
960#undef SET_ITEM
961#undef SET_ITEM_INT
962#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100963#undef SET_ITEM_WSTR
964#undef SET_ITEM_WSTRLIST
965}
966
967
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100968static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200969config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200970{
Victor Stinner20004952019-03-26 02:31:11 +0100971 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200972}
973
974
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100975/* Get a copy of the environment variable as wchar_t*.
976 Return 0 on success, but *dest can be NULL.
977 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200978static PyStatus
979config_get_env_dup(PyConfig *config,
980 wchar_t **dest,
981 wchar_t *wname, char *name,
982 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200983{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200984 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100985 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200986
Victor Stinner20004952019-03-26 02:31:11 +0100987 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200988 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200989 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200990 }
991
992#ifdef MS_WINDOWS
993 const wchar_t *var = _wgetenv(wname);
994 if (!var || var[0] == '\0') {
995 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200996 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200997 }
998
Victor Stinner331a6a52019-05-27 16:39:22 +0200999 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +02001000#else
1001 const char *var = getenv(name);
1002 if (!var || var[0] == '\0') {
1003 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001004 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001005 }
1006
Victor Stinner331a6a52019-05-27 16:39:22 +02001007 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001008#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001009}
1010
1011
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001012#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001013 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001014
1015
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001016static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001017config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001018{
Victor Stinner022be022019-05-22 23:58:50 +02001019 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1020 /* Python and Isolated configuration ignore global variables */
1021 return;
1022 }
1023
Victor Stinner6c785c02018-08-01 17:56:14 +02001024#define COPY_FLAG(ATTR, VALUE) \
1025 if (config->ATTR == -1) { \
1026 config->ATTR = VALUE; \
1027 }
1028#define COPY_NOT_FLAG(ATTR, VALUE) \
1029 if (config->ATTR == -1) { \
1030 config->ATTR = !(VALUE); \
1031 }
1032
Victor Stinner20004952019-03-26 02:31:11 +01001033 COPY_FLAG(isolated, Py_IsolatedFlag);
1034 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001035 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1036 COPY_FLAG(inspect, Py_InspectFlag);
1037 COPY_FLAG(interactive, Py_InteractiveFlag);
1038 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1039 COPY_FLAG(parser_debug, Py_DebugFlag);
1040 COPY_FLAG(verbose, Py_VerboseFlag);
1041 COPY_FLAG(quiet, Py_QuietFlag);
1042#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001043 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1044#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001045 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001046
Victor Stinner6c785c02018-08-01 17:56:14 +02001047 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1048 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1049 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1050 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1051
Victor Stinner6c785c02018-08-01 17:56:14 +02001052#undef COPY_FLAG
1053#undef COPY_NOT_FLAG
1054}
1055
1056
1057/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001058static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001059config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001060{
1061#define COPY_FLAG(ATTR, VAR) \
1062 if (config->ATTR != -1) { \
1063 VAR = config->ATTR; \
1064 }
1065#define COPY_NOT_FLAG(ATTR, VAR) \
1066 if (config->ATTR != -1) { \
1067 VAR = !config->ATTR; \
1068 }
1069
Victor Stinner20004952019-03-26 02:31:11 +01001070 COPY_FLAG(isolated, Py_IsolatedFlag);
1071 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001072 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1073 COPY_FLAG(inspect, Py_InspectFlag);
1074 COPY_FLAG(interactive, Py_InteractiveFlag);
1075 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1076 COPY_FLAG(parser_debug, Py_DebugFlag);
1077 COPY_FLAG(verbose, Py_VerboseFlag);
1078 COPY_FLAG(quiet, Py_QuietFlag);
1079#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001080 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1081#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001082 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001083
Victor Stinner6c785c02018-08-01 17:56:14 +02001084 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1085 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1086 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1087 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1088
Victor Stinner6c785c02018-08-01 17:56:14 +02001089 /* Random or non-zero hash seed */
1090 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1091 config->hash_seed != 0);
1092
1093#undef COPY_FLAG
1094#undef COPY_NOT_FLAG
1095}
1096
1097
1098/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1099 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001100static PyStatus
1101config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001102{
Victor Stinner331a6a52019-05-27 16:39:22 +02001103 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001104
Victor Stinner6c785c02018-08-01 17:56:14 +02001105 /* If Py_SetProgramName() was called, use its value */
1106 const wchar_t *program_name = _Py_path_config.program_name;
1107 if (program_name != NULL) {
1108 config->program_name = _PyMem_RawWcsdup(program_name);
1109 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001110 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001111 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001112 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001113 }
1114
1115#ifdef __APPLE__
1116 /* On MacOS X, when the Python interpreter is embedded in an
1117 application bundle, it gets executed by a bootstrapping script
1118 that does os.execve() with an argv[0] that's different from the
1119 actual Python executable. This is needed to keep the Finder happy,
1120 or rather, to work around Apple's overly strict requirements of
1121 the process name. However, we still need a usable sys.executable,
1122 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001123 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001124 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001125 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001126 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001127 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1128 "PYTHONEXECUTABLE environment variable");
1129 if (_PyStatus_EXCEPTION(status)) {
1130 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001131 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001132 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001133 }
1134#ifdef WITH_NEXT_FRAMEWORK
1135 else {
1136 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1137 if (pyvenv_launcher && *pyvenv_launcher) {
1138 /* Used by Mac/Tools/pythonw.c to forward
1139 * the argv0 of the stub executable
1140 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001141 status = CONFIG_SET_BYTES_STR(config,
1142 &config->program_name,
1143 pyvenv_launcher,
1144 "__PYVENV_LAUNCHER__ environment variable");
1145 if (_PyStatus_EXCEPTION(status)) {
1146 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001147 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001148
1149 /*
1150 * This environment variable is used to communicate between
1151 * the stub launcher and the real interpreter and isn't needed
1152 * beyond this point.
1153 *
1154 * Clean up to avoid problems when launching other programs
1155 * later on.
1156 */
1157 (void)unsetenv("__PYVENV_LAUNCHER__");
1158
Victor Stinner331a6a52019-05-27 16:39:22 +02001159 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001160 }
1161 }
1162#endif /* WITH_NEXT_FRAMEWORK */
1163#endif /* __APPLE__ */
1164
Victor Stinnerfed02e12019-05-17 11:12:09 +02001165 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001166 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001167 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1168 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1169 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001170 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001171 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001172 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001173 }
1174
Victor Stinnerfed02e12019-05-17 11:12:09 +02001175 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001176#ifdef MS_WINDOWS
1177 const wchar_t *default_program_name = L"python";
1178#else
1179 const wchar_t *default_program_name = L"python3";
1180#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001181 status = PyConfig_SetString(config, &config->program_name,
1182 default_program_name);
1183 if (_PyStatus_EXCEPTION(status)) {
1184 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001185 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001186 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001187}
1188
Victor Stinner331a6a52019-05-27 16:39:22 +02001189static PyStatus
1190config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001191{
1192 assert(config->executable == NULL);
1193
1194 /* If Py_SetProgramFullPath() was called, use its value */
1195 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1196 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001197 PyStatus status = PyConfig_SetString(config,
1198 &config->executable,
1199 program_full_path);
1200 if (_PyStatus_EXCEPTION(status)) {
1201 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001202 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001203 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001204 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001205 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001206}
Victor Stinner6c785c02018-08-01 17:56:14 +02001207
Victor Stinner4fffd382019-03-06 01:44:31 +01001208
Victor Stinner6c785c02018-08-01 17:56:14 +02001209static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001210config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001211{
Victor Stinner74f65682019-03-15 15:08:05 +01001212 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001213}
1214
1215
Victor Stinner331a6a52019-05-27 16:39:22 +02001216static PyStatus
1217config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001218{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001219 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001220
1221 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001222 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001223 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001224 PyStatus status = PyConfig_SetString(config, &config->home, home);
1225 if (_PyStatus_EXCEPTION(status)) {
1226 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001227 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001228 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001229 }
1230
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001231 return CONFIG_GET_ENV_DUP(config, &config->home,
1232 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001233}
1234
1235
Victor Stinner331a6a52019-05-27 16:39:22 +02001236static PyStatus
1237config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001238{
Victor Stinner331a6a52019-05-27 16:39:22 +02001239 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001240
1241 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1242 /* Convert a text seed to a numeric one */
1243 if (seed_text && strcmp(seed_text, "random") != 0) {
1244 const char *endptr = seed_text;
1245 unsigned long seed;
1246 errno = 0;
1247 seed = strtoul(seed_text, (char **)&endptr, 10);
1248 if (*endptr != '\0'
1249 || seed > 4294967295UL
1250 || (errno == ERANGE && seed == ULONG_MAX))
1251 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001252 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001253 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001254 }
1255 /* Use a specific hash */
1256 config->use_hash_seed = 1;
1257 config->hash_seed = seed;
1258 }
1259 else {
1260 /* Use a random hash */
1261 config->use_hash_seed = 0;
1262 config->hash_seed = 0;
1263 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001264 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001265}
1266
1267
Victor Stinner6c785c02018-08-01 17:56:14 +02001268static int
1269config_wstr_to_int(const wchar_t *wstr, int *result)
1270{
1271 const wchar_t *endptr = wstr;
1272 errno = 0;
1273 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1274 if (*endptr != '\0' || errno == ERANGE) {
1275 return -1;
1276 }
1277 if (value < INT_MIN || value > INT_MAX) {
1278 return -1;
1279 }
1280
1281 *result = (int)value;
1282 return 0;
1283}
1284
1285
Victor Stinner331a6a52019-05-27 16:39:22 +02001286static PyStatus
1287config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001288{
Victor Stinner331a6a52019-05-27 16:39:22 +02001289 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001290 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001291
Victor Stinner6c785c02018-08-01 17:56:14 +02001292 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001293 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1294 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1295 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1296 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001297
1298 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001299 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001300 if (dont_write_bytecode) {
1301 config->write_bytecode = 0;
1302 }
1303
1304 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001305 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001306 if (no_user_site_directory) {
1307 config->user_site_directory = 0;
1308 }
1309
1310 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001311 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001312 if (unbuffered_stdio) {
1313 config->buffered_stdio = 0;
1314 }
1315
1316#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001317 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001318 "PYTHONLEGACYWINDOWSSTDIO");
1319#endif
1320
Victor Stinner331a6a52019-05-27 16:39:22 +02001321 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001322 config->dump_refs = 1;
1323 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001324 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001325 config->malloc_stats = 1;
1326 }
1327
Victor Stinner331a6a52019-05-27 16:39:22 +02001328 if (config->pythonpath_env == NULL) {
1329 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1330 L"PYTHONPATH", "PYTHONPATH");
1331 if (_PyStatus_EXCEPTION(status)) {
1332 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001333 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001334 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001335
1336 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001337 status = config_init_hash_seed(config);
1338 if (_PyStatus_EXCEPTION(status)) {
1339 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001340 }
1341 }
1342
Victor Stinner331a6a52019-05-27 16:39:22 +02001343 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001344}
1345
1346
Victor Stinner331a6a52019-05-27 16:39:22 +02001347static PyStatus
1348config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001349{
1350 int nframe;
1351 int valid;
1352
Victor Stinner331a6a52019-05-27 16:39:22 +02001353 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001354 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001355 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001356 valid = (nframe >= 0);
1357 }
1358 else {
1359 valid = 0;
1360 }
1361 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001362 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001363 }
1364 config->tracemalloc = nframe;
1365 }
1366
1367 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1368 if (xoption) {
1369 const wchar_t *sep = wcschr(xoption, L'=');
1370 if (sep) {
1371 if (!config_wstr_to_int(sep + 1, &nframe)) {
1372 valid = (nframe >= 0);
1373 }
1374 else {
1375 valid = 0;
1376 }
1377 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001378 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1379 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001380 }
1381 }
1382 else {
1383 /* -X tracemalloc behaves as -X tracemalloc=1 */
1384 nframe = 1;
1385 }
1386 config->tracemalloc = nframe;
1387 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001388 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001389}
1390
1391
Victor Stinner331a6a52019-05-27 16:39:22 +02001392static PyStatus
1393config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001394{
1395 assert(config->pycache_prefix == NULL);
1396
1397 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1398 if (xoption) {
1399 const wchar_t *sep = wcschr(xoption, L'=');
1400 if (sep && wcslen(sep) > 1) {
1401 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1402 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001403 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001404 }
1405 }
1406 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001407 // PYTHONPYCACHEPREFIX env var ignored
1408 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001409 config->pycache_prefix = NULL;
1410 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001411 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001412 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001413
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001414 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1415 L"PYTHONPYCACHEPREFIX",
1416 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001417}
1418
1419
Victor Stinner331a6a52019-05-27 16:39:22 +02001420static PyStatus
1421config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001422{
1423 /* More complex options configured by env var and -X option */
1424 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001425 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001426 || config_get_xoption(config, L"faulthandler")) {
1427 config->faulthandler = 1;
1428 }
1429 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001430 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001431 || config_get_xoption(config, L"importtime")) {
1432 config->import_time = 1;
1433 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001434
Pablo Galindoc5fc1562020-04-22 23:29:27 +01001435 if (config_get_env(config, "PYTHONOLDPARSER")
1436 || config_get_xoption(config, L"oldparser")) {
Victor Stinner1def7752020-04-23 03:03:24 +02001437 config->_use_peg_parser = 0;
Pablo Galindoc5fc1562020-04-22 23:29:27 +01001438 }
1439
Victor Stinner331a6a52019-05-27 16:39:22 +02001440 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001441 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001442 status = config_init_tracemalloc(config);
1443 if (_PyStatus_EXCEPTION(status)) {
1444 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001445 }
1446 }
1447
1448 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001449 status = config_init_pycache_prefix(config);
1450 if (_PyStatus_EXCEPTION(status)) {
1451 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001452 }
1453 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001454 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001455}
1456
1457
Victor Stinner709d23d2019-05-02 14:56:30 -04001458static const wchar_t *
Andy Lesteraa450a02020-03-07 11:36:04 -06001459config_get_stdio_errors(void)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001460{
1461#ifndef MS_WINDOWS
1462 const char *loc = setlocale(LC_CTYPE, NULL);
1463 if (loc != NULL) {
1464 /* surrogateescape is the default in the legacy C and POSIX locales */
1465 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001466 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001467 }
1468
1469#ifdef PY_COERCE_C_LOCALE
1470 /* surrogateescape is the default in locale coercion target locales */
1471 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001472 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001473 }
1474#endif
1475 }
1476
Victor Stinner709d23d2019-05-02 14:56:30 -04001477 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001478#else
1479 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001480 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001481#endif
1482}
1483
1484
Victor Stinner331a6a52019-05-27 16:39:22 +02001485static PyStatus
1486config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001487{
1488#ifdef MS_WINDOWS
1489 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001490 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001491 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001492#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001493 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001494#else
1495 const char *encoding = nl_langinfo(CODESET);
1496 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001497 return _PyStatus_ERR("failed to get the locale encoding: "
1498 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001499 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001500 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001501 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001502 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001503 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001504#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001505}
1506
1507
Victor Stinner331a6a52019-05-27 16:39:22 +02001508static PyStatus
1509config_init_stdio_encoding(PyConfig *config,
1510 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001511{
Victor Stinner331a6a52019-05-27 16:39:22 +02001512 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001513
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001514 /* If Py_SetStandardStreamEncoding() have been called, use these
1515 parameters. */
1516 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001517 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1518 _Py_StandardStreamEncoding,
1519 "_Py_StandardStreamEncoding");
1520 if (_PyStatus_EXCEPTION(status)) {
1521 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001522 }
1523 }
1524
1525 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001526 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1527 _Py_StandardStreamErrors,
1528 "_Py_StandardStreamErrors");
1529 if (_PyStatus_EXCEPTION(status)) {
1530 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001531 }
1532 }
1533
1534 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001535 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001536 }
1537
1538 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001539 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001540 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001541 char *pythonioencoding = _PyMem_RawStrdup(opt);
1542 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001543 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001544 }
1545
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001546 char *errors = strchr(pythonioencoding, ':');
1547 if (errors) {
1548 *errors = '\0';
1549 errors++;
1550 if (!errors[0]) {
1551 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001552 }
1553 }
1554
1555 /* Does PYTHONIOENCODING contain an encoding? */
1556 if (pythonioencoding[0]) {
1557 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001558 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1559 pythonioencoding,
1560 "PYTHONIOENCODING environment variable");
1561 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001562 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001563 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001564 }
1565 }
1566
1567 /* If the encoding is set but not the error handler,
1568 use "strict" error handler by default.
1569 PYTHONIOENCODING=latin1 behaves as
1570 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001571 if (!errors) {
1572 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001573 }
1574 }
1575
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001576 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001577 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1578 errors,
1579 "PYTHONIOENCODING environment variable");
1580 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001581 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001582 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001583 }
1584 }
1585
1586 PyMem_RawFree(pythonioencoding);
1587 }
1588
1589 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001590 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001591 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001592 status = PyConfig_SetString(config, &config->stdio_encoding,
1593 L"utf-8");
1594 if (_PyStatus_EXCEPTION(status)) {
1595 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001596 }
1597 }
1598 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001599 status = PyConfig_SetString(config, &config->stdio_errors,
1600 L"surrogateescape");
1601 if (_PyStatus_EXCEPTION(status)) {
1602 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001603 }
1604 }
1605 }
1606
1607 /* Choose the default error handler based on the current locale. */
1608 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001609 status = config_get_locale_encoding(config, &config->stdio_encoding);
1610 if (_PyStatus_EXCEPTION(status)) {
1611 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001612 }
1613 }
1614 if (config->stdio_errors == NULL) {
Andy Lesteraa450a02020-03-07 11:36:04 -06001615 const wchar_t *errors = config_get_stdio_errors();
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001616 assert(errors != NULL);
1617
Victor Stinner331a6a52019-05-27 16:39:22 +02001618 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1619 if (_PyStatus_EXCEPTION(status)) {
1620 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001621 }
1622 }
1623
Victor Stinner331a6a52019-05-27 16:39:22 +02001624 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001625}
1626
1627
Victor Stinner331a6a52019-05-27 16:39:22 +02001628static PyStatus
1629config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001630{
Victor Stinner331a6a52019-05-27 16:39:22 +02001631 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001632
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001633 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001634#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001635 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001636#else
Victor Stinnere2510952019-05-02 11:28:57 -04001637
1638#ifdef MS_WINDOWS
1639 if (preconfig->legacy_windows_fs_encoding) {
1640 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001641 status = PyConfig_SetString(config, &config->filesystem_encoding,
1642 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001643 }
1644 else
1645#endif
Victor Stinner20004952019-03-26 02:31:11 +01001646 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001647 status = PyConfig_SetString(config, &config->filesystem_encoding,
1648 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001649 }
Victor Stinnere2510952019-05-02 11:28:57 -04001650#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001651 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001652 status = PyConfig_SetString(config, &config->filesystem_encoding,
1653 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001654 }
Victor Stinnere2510952019-05-02 11:28:57 -04001655#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001656 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001657#ifdef MS_WINDOWS
1658 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001659 status = PyConfig_SetString(config, &config->filesystem_encoding,
1660 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001661#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001662 status = config_get_locale_encoding(config,
1663 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001664#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001665 }
Victor Stinnere2510952019-05-02 11:28:57 -04001666#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001667
Victor Stinner331a6a52019-05-27 16:39:22 +02001668 if (_PyStatus_EXCEPTION(status)) {
1669 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001670 }
1671 }
1672
1673 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001674 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001675#ifdef MS_WINDOWS
1676 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001677 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001678 }
1679 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001680 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001681 }
1682#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001683 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001684#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001685 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1686 if (_PyStatus_EXCEPTION(status)) {
1687 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001688 }
1689 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001690 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001691}
1692
1693
Victor Stinner331a6a52019-05-27 16:39:22 +02001694static PyStatus
1695config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001696{
Victor Stinner331a6a52019-05-27 16:39:22 +02001697 PyStatus status;
1698 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001699
Victor Stinner20004952019-03-26 02:31:11 +01001700 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001701 status = config_read_env_vars(config);
1702 if (_PyStatus_EXCEPTION(status)) {
1703 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001704 }
1705 }
1706
1707 /* -X options */
1708 if (config_get_xoption(config, L"showrefcount")) {
1709 config->show_ref_count = 1;
1710 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001711
Victor Stinner331a6a52019-05-27 16:39:22 +02001712 status = config_read_complex_options(config);
1713 if (_PyStatus_EXCEPTION(status)) {
1714 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001715 }
1716
Victor Stinner6c785c02018-08-01 17:56:14 +02001717 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001718 status = config_init_home(config);
1719 if (_PyStatus_EXCEPTION(status)) {
1720 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001721 }
1722 }
1723
Steve Dower177a41a2018-11-17 20:41:48 -08001724 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001725 status = config_init_executable(config);
1726 if (_PyStatus_EXCEPTION(status)) {
1727 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001728 }
1729 }
1730
Victor Stinner6c785c02018-08-01 17:56:14 +02001731 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001732 status = _PyConfig_InitPathConfig(config);
1733 if (_PyStatus_EXCEPTION(status)) {
1734 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001735 }
1736 }
1737
1738 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001739 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001740 if (config->faulthandler < 0) {
1741 config->faulthandler = 1;
1742 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001743 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001744 if (config->faulthandler < 0) {
1745 config->faulthandler = 0;
1746 }
1747 if (config->tracemalloc < 0) {
1748 config->tracemalloc = 0;
1749 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001750 if (config->use_hash_seed < 0) {
1751 config->use_hash_seed = 0;
1752 config->hash_seed = 0;
1753 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001754
Victor Stinner70fead22018-08-29 13:45:34 +02001755 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001756 status = config_init_fs_encoding(config, preconfig);
1757 if (_PyStatus_EXCEPTION(status)) {
1758 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001759 }
1760 }
1761
Victor Stinner331a6a52019-05-27 16:39:22 +02001762 status = config_init_stdio_encoding(config, preconfig);
1763 if (_PyStatus_EXCEPTION(status)) {
1764 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001765 }
1766
Victor Stinner62599762019-03-15 16:03:23 +01001767 if (config->argv.length < 1) {
1768 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001769 status = PyWideStringList_Append(&config->argv, L"");
1770 if (_PyStatus_EXCEPTION(status)) {
1771 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001772 }
1773 }
Victor Stinner870b0352019-05-17 03:15:12 +02001774
1775 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001776 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1777 L"default");
1778 if (_PyStatus_EXCEPTION(status)) {
1779 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001780 }
1781 }
1782
1783 if (config->configure_c_stdio < 0) {
1784 config->configure_c_stdio = 1;
1785 }
1786
Victor Stinner331a6a52019-05-27 16:39:22 +02001787 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001788}
Victor Stinner5ed69952018-11-06 15:59:52 +01001789
1790
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001791static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001792config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001793{
1794#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1795 /* don't translate newlines (\r\n <=> \n) */
1796 _setmode(fileno(stdin), O_BINARY);
1797 _setmode(fileno(stdout), O_BINARY);
1798 _setmode(fileno(stderr), O_BINARY);
1799#endif
1800
1801 if (!config->buffered_stdio) {
1802#ifdef HAVE_SETVBUF
1803 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1804 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1805 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1806#else /* !HAVE_SETVBUF */
1807 setbuf(stdin, (char *)NULL);
1808 setbuf(stdout, (char *)NULL);
1809 setbuf(stderr, (char *)NULL);
1810#endif /* !HAVE_SETVBUF */
1811 }
1812 else if (config->interactive) {
1813#ifdef MS_WINDOWS
1814 /* Doesn't have to have line-buffered -- use unbuffered */
1815 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1816 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1817#else /* !MS_WINDOWS */
1818#ifdef HAVE_SETVBUF
1819 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1820 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1821#endif /* HAVE_SETVBUF */
1822#endif /* !MS_WINDOWS */
1823 /* Leave stderr alone - it should be unbuffered anyway. */
1824 }
1825}
1826
1827
1828/* Write the configuration:
1829
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001830 - set Py_xxx global configuration variables
1831 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001832void
Victor Stinner331a6a52019-05-27 16:39:22 +02001833_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001834{
Victor Stinner331a6a52019-05-27 16:39:22 +02001835 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001836
1837 if (config->configure_c_stdio) {
1838 config_init_stdio(config);
1839 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001840
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001841 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001842 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001843 preconfig->isolated = config->isolated;
1844 preconfig->use_environment = config->use_environment;
1845 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001846}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001847
1848
Victor Stinner331a6a52019-05-27 16:39:22 +02001849/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001850
1851static void
Victor Stinner2f549082019-03-29 15:13:46 +01001852config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001853{
Victor Stinner2f549082019-03-29 15:13:46 +01001854 FILE *f = error ? stderr : stdout;
1855
1856 fprintf(f, usage_line, program);
1857 if (error)
1858 fprintf(f, "Try `python -h' for more information.\n");
1859 else {
1860 fputs(usage_1, f);
1861 fputs(usage_2, f);
1862 fputs(usage_3, f);
1863 fprintf(f, usage_4, (wint_t)DELIM);
1864 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1865 fputs(usage_6, f);
1866 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001867}
1868
1869
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001870/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001871static PyStatus
1872config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001873 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001874{
Victor Stinner331a6a52019-05-27 16:39:22 +02001875 PyStatus status;
1876 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001877 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001878 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001879
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001880 _PyOS_ResetGetOpt();
1881 do {
1882 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001883 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001884 if (c == EOF) {
1885 break;
1886 }
1887
1888 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001889 if (config->run_command == NULL) {
1890 /* -c is the last option; following arguments
1891 that look like options are left for the
1892 command to interpret. */
1893 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1894 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1895 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001896 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001897 }
1898 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1899 command[len - 2] = '\n';
1900 command[len - 1] = 0;
1901 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001902 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001903 break;
1904 }
1905
1906 if (c == 'm') {
1907 /* -m is the last option; following arguments
1908 that look like options are left for the
1909 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001910 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001911 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1912 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001913 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001914 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001915 }
1916 break;
1917 }
1918
1919 switch (c) {
1920 case 0:
1921 // Handle long option.
1922 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001923 if (wcscmp(_PyOS_optarg, L"always") == 0
1924 || wcscmp(_PyOS_optarg, L"never") == 0
1925 || wcscmp(_PyOS_optarg, L"default") == 0)
1926 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001927 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1928 _PyOS_optarg);
1929 if (_PyStatus_EXCEPTION(status)) {
1930 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001931 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001932 } else {
1933 fprintf(stderr, "--check-hash-based-pycs must be one of "
1934 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001935 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001936 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001937 }
1938 break;
1939
1940 case 'b':
1941 config->bytes_warning++;
1942 break;
1943
1944 case 'd':
1945 config->parser_debug++;
1946 break;
1947
1948 case 'i':
1949 config->inspect++;
1950 config->interactive++;
1951 break;
1952
Victor Stinner6dcb5422019-03-05 02:44:12 +01001953 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001954 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001955 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001956 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001957 break;
1958
1959 /* case 'J': reserved for Jython */
1960
1961 case 'O':
1962 config->optimization_level++;
1963 break;
1964
1965 case 'B':
1966 config->write_bytecode = 0;
1967 break;
1968
1969 case 's':
1970 config->user_site_directory = 0;
1971 break;
1972
1973 case 'S':
1974 config->site_import = 0;
1975 break;
1976
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001977 case 't':
1978 /* ignored for backwards compatibility */
1979 break;
1980
1981 case 'u':
1982 config->buffered_stdio = 0;
1983 break;
1984
1985 case 'v':
1986 config->verbose++;
1987 break;
1988
1989 case 'x':
1990 config->skip_source_first_line = 1;
1991 break;
1992
1993 case 'h':
1994 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001995 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001996 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001997
1998 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01001999 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002000 break;
2001
2002 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002003 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2004 if (_PyStatus_EXCEPTION(status)) {
2005 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002006 }
2007 break;
2008
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002009 case 'q':
2010 config->quiet++;
2011 break;
2012
2013 case 'R':
2014 config->use_hash_seed = 0;
2015 break;
2016
2017 /* This space reserved for other options */
2018
2019 default:
2020 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002021 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002022 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002023 }
2024 } while (1);
2025
Victor Stinner2f549082019-03-29 15:13:46 +01002026 if (print_version) {
2027 printf("Python %s\n",
2028 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002029 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002030 }
2031
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002032 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002033 && _PyOS_optind < argv->length
2034 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002035 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002036 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002037 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002038 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002039 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002040 }
2041 }
2042
2043 if (config->run_command != NULL || config->run_module != NULL) {
2044 /* Backup _PyOS_optind */
2045 _PyOS_optind--;
2046 }
2047
Victor Stinnerae239f62019-05-16 17:02:56 +02002048 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002049
Victor Stinner331a6a52019-05-27 16:39:22 +02002050 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002051}
2052
2053
2054#ifdef MS_WINDOWS
2055# define WCSTOK wcstok_s
2056#else
2057# define WCSTOK wcstok
2058#endif
2059
2060/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002061static PyStatus
2062config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002063{
Victor Stinner331a6a52019-05-27 16:39:22 +02002064 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002065 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2066 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002067 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002068 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002069 if (_PyStatus_EXCEPTION(status)) {
2070 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002071 }
2072
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002073 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002074 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002075 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002076 }
2077
2078
2079 wchar_t *warning, *context = NULL;
2080 for (warning = WCSTOK(env, L",", &context);
2081 warning != NULL;
2082 warning = WCSTOK(NULL, L",", &context))
2083 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002084 status = PyWideStringList_Append(warnoptions, warning);
2085 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002086 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002087 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002088 }
2089 }
2090 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002091 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002092}
2093
2094
Victor Stinner331a6a52019-05-27 16:39:22 +02002095static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002096warnoptions_append(PyConfig *config, PyWideStringList *options,
2097 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002098{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002099 /* config_init_warnoptions() add existing config warnoptions at the end:
2100 ensure that the new option is not already present in this list to
2101 prevent change the options order whne config_init_warnoptions() is
2102 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002103 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002104 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002105 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002106 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002107 if (_PyWideStringList_Find(options, option)) {
2108 /* Already present: do nothing */
2109 return _PyStatus_OK();
2110 }
2111 return PyWideStringList_Append(options, option);
2112}
2113
2114
2115static PyStatus
2116warnoptions_extend(PyConfig *config, PyWideStringList *options,
2117 const PyWideStringList *options2)
2118{
2119 const Py_ssize_t len = options2->length;
2120 wchar_t *const *items = options2->items;
2121
2122 for (Py_ssize_t i = 0; i < len; i++) {
2123 PyStatus status = warnoptions_append(config, options, items[i]);
2124 if (_PyStatus_EXCEPTION(status)) {
2125 return status;
2126 }
2127 }
2128 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002129}
2130
2131
Victor Stinner331a6a52019-05-27 16:39:22 +02002132static PyStatus
2133config_init_warnoptions(PyConfig *config,
2134 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002135 const PyWideStringList *env_warnoptions,
2136 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002137{
Victor Stinner331a6a52019-05-27 16:39:22 +02002138 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002139 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002140
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002141 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002142 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002143 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002144 * - PyConfig.dev_mode: "default" filter
2145 * - PYTHONWARNINGS environment variable
2146 * - '-W' command line options
2147 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2148 * "default::BytesWarning" or "error::BytesWarning" filter
2149 * - early PySys_AddWarnOption() calls
2150 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002151 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002152 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2153 * module works on the basis of "the most recently added filter will be
2154 * checked first", we add the lowest precedence entries first so that later
2155 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002156 */
2157
Victor Stinner20004952019-03-26 02:31:11 +01002158 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002159 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002160 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002161 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002162 }
2163 }
2164
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002165 status = warnoptions_extend(config, &options, env_warnoptions);
2166 if (_PyStatus_EXCEPTION(status)) {
2167 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002168 }
2169
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002170 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2171 if (_PyStatus_EXCEPTION(status)) {
2172 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002173 }
2174
2175 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2176 * don't even try to emit a warning, so we skip setting the filter in that
2177 * case.
2178 */
2179 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002180 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002181 if (config->bytes_warning> 1) {
2182 filter = L"error::BytesWarning";
2183 }
2184 else {
2185 filter = L"default::BytesWarning";
2186 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002187 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002188 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002189 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002190 }
2191 }
Victor Stinner120b7072019-08-23 18:03:08 +01002192
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002193 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002194 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002195 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002196 }
2197
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002198 /* Always add all PyConfig.warnoptions options */
2199 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2200 if (_PyStatus_EXCEPTION(status)) {
2201 goto error;
2202 }
2203
2204 _PyWideStringList_Clear(&config->warnoptions);
2205 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002206 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002207
2208error:
2209 _PyWideStringList_Clear(&options);
2210 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002211}
2212
2213
Victor Stinner331a6a52019-05-27 16:39:22 +02002214static PyStatus
2215config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002216{
Victor Stinner331a6a52019-05-27 16:39:22 +02002217 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002218 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002219
Victor Stinner74f65682019-03-15 15:08:05 +01002220 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002221 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002222 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002223 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2224 if (_PyStatus_EXCEPTION(status)) {
2225 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002226 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002227 }
2228 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002229 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002230 slice.length = cmdline_argv->length - opt_index;
2231 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002232 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2233 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002234 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002235 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002236 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002237
2238 wchar_t *arg0 = NULL;
2239 if (config->run_command != NULL) {
2240 /* Force sys.argv[0] = '-c' */
2241 arg0 = L"-c";
2242 }
2243 else if (config->run_module != NULL) {
2244 /* Force sys.argv[0] = '-m'*/
2245 arg0 = L"-m";
2246 }
Victor Stinner3939c322019-06-25 15:02:43 +02002247
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002248 if (arg0 != NULL) {
2249 arg0 = _PyMem_RawWcsdup(arg0);
2250 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002251 _PyWideStringList_Clear(&config_argv);
2252 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002253 }
2254
Victor Stinnerfa153762019-03-20 04:25:38 +01002255 PyMem_RawFree(config_argv.items[0]);
2256 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002257 }
2258
Victor Stinner331a6a52019-05-27 16:39:22 +02002259 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002260 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002261 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002262}
2263
2264
Victor Stinner331a6a52019-05-27 16:39:22 +02002265static PyStatus
2266core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002267{
Victor Stinner331a6a52019-05-27 16:39:22 +02002268 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002269
Victor Stinnercab5d072019-05-17 19:01:14 +02002270 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002271 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2272 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002273 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002274 }
2275
Victor Stinner331a6a52019-05-27 16:39:22 +02002276 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002277
2278 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2279 if (_PyStatus_EXCEPTION(status)) {
2280 return status;
2281 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002282
Victor Stinner331a6a52019-05-27 16:39:22 +02002283 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002284
Victor Stinner331a6a52019-05-27 16:39:22 +02002285 status = _PyPreCmdline_Read(precmdline, &preconfig);
2286 if (_PyStatus_EXCEPTION(status)) {
2287 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002288 }
2289
Victor Stinner331a6a52019-05-27 16:39:22 +02002290 status = _PyPreCmdline_SetConfig(precmdline, config);
2291 if (_PyStatus_EXCEPTION(status)) {
2292 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002293 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002294 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002295}
2296
2297
Victor Stinner3939c322019-06-25 15:02:43 +02002298/* Get run_filename absolute path */
2299static PyStatus
2300config_run_filename_abspath(PyConfig *config)
2301{
2302 if (!config->run_filename) {
2303 return _PyStatus_OK();
2304 }
2305
2306#ifndef MS_WINDOWS
2307 if (_Py_isabs(config->run_filename)) {
2308 /* path is already absolute */
2309 return _PyStatus_OK();
2310 }
2311#endif
2312
2313 wchar_t *abs_filename;
2314 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2315 /* failed to get the absolute path of the command line filename:
2316 ignore the error, keep the relative path */
2317 return _PyStatus_OK();
2318 }
2319 if (abs_filename == NULL) {
2320 return _PyStatus_NO_MEMORY();
2321 }
2322
2323 PyMem_RawFree(config->run_filename);
2324 config->run_filename = abs_filename;
2325 return _PyStatus_OK();
2326}
2327
2328
Victor Stinner331a6a52019-05-27 16:39:22 +02002329static PyStatus
2330config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002331{
Victor Stinner331a6a52019-05-27 16:39:22 +02002332 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002333 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2334 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2335 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002336
Victor Stinnerae239f62019-05-16 17:02:56 +02002337 if (config->parse_argv < 0) {
2338 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002339 }
Victor Stinner870b0352019-05-17 03:15:12 +02002340
Victor Stinnerfed02e12019-05-17 11:12:09 +02002341 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002342 status = config_init_program_name(config);
2343 if (_PyStatus_EXCEPTION(status)) {
2344 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002345 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002346 }
Victor Stinner2f549082019-03-29 15:13:46 +01002347
Victor Stinnerae239f62019-05-16 17:02:56 +02002348 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002349 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002350 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2351 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002352 goto done;
2353 }
2354
Victor Stinner3939c322019-06-25 15:02:43 +02002355 status = config_run_filename_abspath(config);
2356 if (_PyStatus_EXCEPTION(status)) {
2357 goto done;
2358 }
2359
Victor Stinner331a6a52019-05-27 16:39:22 +02002360 status = config_update_argv(config, opt_index);
2361 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002362 goto done;
2363 }
Victor Stinner2f549082019-03-29 15:13:46 +01002364 }
Victor Stinner3939c322019-06-25 15:02:43 +02002365 else {
2366 status = config_run_filename_abspath(config);
2367 if (_PyStatus_EXCEPTION(status)) {
2368 goto done;
2369 }
2370 }
Victor Stinner2f549082019-03-29 15:13:46 +01002371
Victor Stinner2f549082019-03-29 15:13:46 +01002372 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002373 status = config_init_env_warnoptions(config, &env_warnoptions);
2374 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002375 goto done;
2376 }
2377 }
2378
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002379 /* Handle early PySys_AddWarnOption() calls */
2380 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2381 if (_PyStatus_EXCEPTION(status)) {
2382 goto done;
2383 }
2384
Victor Stinner331a6a52019-05-27 16:39:22 +02002385 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002386 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002387 &env_warnoptions,
2388 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002389 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002390 goto done;
2391 }
2392
Victor Stinner331a6a52019-05-27 16:39:22 +02002393 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002394
2395done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002396 _PyWideStringList_Clear(&cmdline_warnoptions);
2397 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002398 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002399 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002400}
2401
2402
Victor Stinner331a6a52019-05-27 16:39:22 +02002403PyStatus
2404_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002405{
Victor Stinner331a6a52019-05-27 16:39:22 +02002406 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2407 if (_PyStatus_EXCEPTION(status)) {
2408 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002409 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002410
Victor Stinner5f38b842019-05-01 02:30:12 +02002411 return _PyArgv_AsWstrList(args, &config->argv);
2412}
2413
2414
Victor Stinner70005ac2019-05-02 15:25:34 -04002415/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2416 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002417PyStatus
2418PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002419{
2420 _PyArgv args = {
2421 .argc = argc,
2422 .use_bytes_argv = 1,
2423 .bytes_argv = argv,
2424 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002425 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002426}
2427
2428
Victor Stinner331a6a52019-05-27 16:39:22 +02002429PyStatus
2430PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002431{
2432 _PyArgv args = {
2433 .argc = argc,
2434 .use_bytes_argv = 0,
2435 .bytes_argv = NULL,
2436 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002437 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002438}
2439
2440
Victor Stinner36242fd2019-07-01 19:13:50 +02002441PyStatus
2442PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2443 Py_ssize_t length, wchar_t **items)
2444{
2445 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2446 if (_PyStatus_EXCEPTION(status)) {
2447 return status;
2448 }
2449
2450 PyWideStringList list2 = {.length = length, .items = items};
2451 if (_PyWideStringList_Copy(list, &list2) < 0) {
2452 return _PyStatus_NO_MEMORY();
2453 }
2454 return _PyStatus_OK();
2455}
2456
2457
Victor Stinner331a6a52019-05-27 16:39:22 +02002458/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002459
2460 * Command line arguments
2461 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002462 * Py_xxx global configuration variables
2463
2464 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002465PyStatus
2466PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002467{
Victor Stinner331a6a52019-05-27 16:39:22 +02002468 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002469 PyWideStringList orig_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002470
Victor Stinner331a6a52019-05-27 16:39:22 +02002471 status = _Py_PreInitializeFromConfig(config, NULL);
2472 if (_PyStatus_EXCEPTION(status)) {
2473 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002474 }
2475
Victor Stinner331a6a52019-05-27 16:39:22 +02002476 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002477
Victor Stinner331a6a52019-05-27 16:39:22 +02002478 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2479 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002480 }
2481
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002482 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002483 status = core_read_precmdline(config, &precmdline);
2484 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002485 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002486 }
2487
Victor Stinner870b0352019-05-17 03:15:12 +02002488 assert(config->isolated >= 0);
2489 if (config->isolated) {
2490 config->use_environment = 0;
2491 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002492 }
2493
Victor Stinner331a6a52019-05-27 16:39:22 +02002494 status = config_read_cmdline(config);
2495 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002496 goto done;
2497 }
2498
Victor Stinner120b7072019-08-23 18:03:08 +01002499 /* Handle early PySys_AddXOption() calls */
2500 status = _PySys_ReadPreinitXOptions(config);
2501 if (_PyStatus_EXCEPTION(status)) {
2502 goto done;
2503 }
2504
Victor Stinner331a6a52019-05-27 16:39:22 +02002505 status = config_read(config);
2506 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002507 goto done;
2508 }
2509
Victor Stinnercab5d072019-05-17 19:01:14 +02002510 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002511 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002512 goto done;
2513 }
2514
2515 /* Check config consistency */
2516 assert(config->isolated >= 0);
2517 assert(config->use_environment >= 0);
2518 assert(config->dev_mode >= 0);
Victor Stinner1def7752020-04-23 03:03:24 +02002519 assert(config->_use_peg_parser >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002520 assert(config->install_signal_handlers >= 0);
2521 assert(config->use_hash_seed >= 0);
2522 assert(config->faulthandler >= 0);
2523 assert(config->tracemalloc >= 0);
2524 assert(config->site_import >= 0);
2525 assert(config->bytes_warning >= 0);
2526 assert(config->inspect >= 0);
2527 assert(config->interactive >= 0);
2528 assert(config->optimization_level >= 0);
2529 assert(config->parser_debug >= 0);
2530 assert(config->write_bytecode >= 0);
2531 assert(config->verbose >= 0);
2532 assert(config->quiet >= 0);
2533 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002534 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002535 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002536 assert(config->buffered_stdio >= 0);
2537 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002538 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002539 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2540 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002541 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2542 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2543 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002544 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002545 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002546 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002547 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002548 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002549 assert(config->prefix != NULL);
2550 assert(config->base_prefix != NULL);
2551 assert(config->exec_prefix != NULL);
2552 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002553 }
2554 assert(config->filesystem_encoding != NULL);
2555 assert(config->filesystem_errors != NULL);
2556 assert(config->stdio_encoding != NULL);
2557 assert(config->stdio_errors != NULL);
2558#ifdef MS_WINDOWS
2559 assert(config->legacy_windows_stdio >= 0);
2560#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002561 /* -c and -m options are exclusive */
2562 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002563 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002564 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002565 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002566
Victor Stinner331a6a52019-05-27 16:39:22 +02002567 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002568
2569done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002570 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002571 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002572 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002573}
Victor Stinner1075d162019-03-25 23:19:57 +01002574
2575
2576PyObject*
2577_Py_GetConfigsAsDict(void)
2578{
Victor Stinner331a6a52019-05-27 16:39:22 +02002579 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002580 PyObject *dict = NULL;
2581
Victor Stinner331a6a52019-05-27 16:39:22 +02002582 result = PyDict_New();
2583 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002584 goto error;
2585 }
2586
Victor Stinner331a6a52019-05-27 16:39:22 +02002587 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002588 dict = _Py_GetGlobalVariablesAsDict();
2589 if (dict == NULL) {
2590 goto error;
2591 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002592 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002593 goto error;
2594 }
2595 Py_CLEAR(dict);
2596
2597 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002598 PyThreadState *tstate = _PyThreadState_GET();
2599 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002600 dict = _PyPreConfig_AsDict(pre_config);
2601 if (dict == NULL) {
2602 goto error;
2603 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002604 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002605 goto error;
2606 }
2607 Py_CLEAR(dict);
2608
2609 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002610 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinner331a6a52019-05-27 16:39:22 +02002611 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002612 if (dict == NULL) {
2613 goto error;
2614 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002615 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002616 goto error;
2617 }
2618 Py_CLEAR(dict);
2619
Victor Stinner331a6a52019-05-27 16:39:22 +02002620 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002621
2622error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002623 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002624 Py_XDECREF(dict);
2625 return NULL;
2626}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002627
2628
2629static void
2630init_dump_ascii_wstr(const wchar_t *str)
2631{
2632 if (str == NULL) {
2633 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002634 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002635 }
2636
2637 PySys_WriteStderr("'");
2638 for (; *str != L'\0'; str++) {
2639 wchar_t ch = *str;
2640 if (ch == L'\'') {
2641 PySys_WriteStderr("\\'");
2642 } else if (0x20 <= ch && ch < 0x7f) {
2643 PySys_WriteStderr("%lc", ch);
2644 }
2645 else if (ch <= 0xff) {
2646 PySys_WriteStderr("\\x%02x", ch);
2647 }
2648#if SIZEOF_WCHAR_T > 2
2649 else if (ch > 0xffff) {
2650 PySys_WriteStderr("\\U%08x", ch);
2651 }
2652#endif
2653 else {
2654 PySys_WriteStderr("\\u%04x", ch);
2655 }
2656 }
2657 PySys_WriteStderr("'");
2658}
2659
2660
2661/* Dump the Python path configuration into sys.stderr */
2662void
2663_Py_DumpPathConfig(PyThreadState *tstate)
2664{
2665 PyObject *exc_type, *exc_value, *exc_tb;
2666 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2667
2668 PySys_WriteStderr("Python path configuration:\n");
2669
2670#define DUMP_CONFIG(NAME, FIELD) \
2671 do { \
2672 PySys_WriteStderr(" " NAME " = "); \
2673 init_dump_ascii_wstr(config->FIELD); \
2674 PySys_WriteStderr("\n"); \
2675 } while (0)
2676
Victor Stinnerda7933e2020-04-13 03:04:28 +02002677 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002678 DUMP_CONFIG("PYTHONHOME", home);
2679 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2680 DUMP_CONFIG("program name", program_name);
2681 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2682 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2683 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2684 PySys_WriteStderr(" import site = %i\n", config->site_import);
2685#undef DUMP_CONFIG
2686
2687#define DUMP_SYS(NAME) \
2688 do { \
2689 obj = PySys_GetObject(#NAME); \
2690 PySys_FormatStderr(" sys.%s = ", #NAME); \
2691 if (obj != NULL) { \
2692 PySys_FormatStderr("%A", obj); \
2693 } \
2694 else { \
2695 PySys_WriteStderr("(not set)"); \
2696 } \
2697 PySys_FormatStderr("\n"); \
2698 } while (0)
2699
2700 PyObject *obj;
2701 DUMP_SYS(_base_executable);
2702 DUMP_SYS(base_prefix);
2703 DUMP_SYS(base_exec_prefix);
2704 DUMP_SYS(executable);
2705 DUMP_SYS(prefix);
2706 DUMP_SYS(exec_prefix);
2707#undef DUMP_SYS
2708
2709 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2710 if (sys_path != NULL && PyList_Check(sys_path)) {
2711 PySys_WriteStderr(" sys.path = [\n");
2712 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2713 for (Py_ssize_t i=0; i < len; i++) {
2714 PyObject *path = PyList_GET_ITEM(sys_path, i);
2715 PySys_FormatStderr(" %A,\n", path);
2716 }
2717 PySys_WriteStderr(" ]\n");
2718 }
2719
2720 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2721}