blob: 185935c05fb286d106fbd47b9ba6b6b6c9d168e2 [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;
Victor Stinner252346a2020-05-01 11:33:44 +0200635 config->_isolated_interpreter = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200636#ifdef MS_WINDOWS
637 config->legacy_windows_stdio = -1;
638#endif
Victor Stinner1def7752020-04-23 03:03:24 +0200639 config->_use_peg_parser = 1;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200640}
641
642
Victor Stinner8462a492019-10-01 12:06:16 +0200643static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200644config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200645{
Victor Stinner8462a492019-10-01 12:06:16 +0200646 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200647
648 config->isolated = 0;
649 config->use_environment = 1;
650 config->site_import = 1;
651 config->bytes_warning = 0;
652 config->inspect = 0;
653 config->interactive = 0;
654 config->optimization_level = 0;
655 config->parser_debug= 0;
656 config->write_bytecode = 1;
657 config->verbose = 0;
658 config->quiet = 0;
659 config->user_site_directory = 1;
660 config->buffered_stdio = 1;
661 config->pathconfig_warnings = 1;
662#ifdef MS_WINDOWS
663 config->legacy_windows_stdio = 0;
664#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200665}
666
667
Victor Stinner8462a492019-10-01 12:06:16 +0200668void
Victor Stinner331a6a52019-05-27 16:39:22 +0200669PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200670{
Victor Stinner8462a492019-10-01 12:06:16 +0200671 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200672
Victor Stinner022be022019-05-22 23:58:50 +0200673 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200674 config->configure_c_stdio = 1;
675 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200676}
677
678
Victor Stinner8462a492019-10-01 12:06:16 +0200679void
Victor Stinner331a6a52019-05-27 16:39:22 +0200680PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200681{
Victor Stinner8462a492019-10-01 12:06:16 +0200682 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200683
Victor Stinner022be022019-05-22 23:58:50 +0200684 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200685 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200686 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200687 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200688 config->dev_mode = 0;
689 config->install_signal_handlers = 0;
690 config->use_hash_seed = 0;
691 config->faulthandler = 0;
692 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200693 config->pathconfig_warnings = 0;
694#ifdef MS_WINDOWS
695 config->legacy_windows_stdio = 0;
696#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200697}
698
699
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200700/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200701PyStatus
702PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200703{
Victor Stinner331a6a52019-05-27 16:39:22 +0200704 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
705 if (_PyStatus_EXCEPTION(status)) {
706 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200707 }
708
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200709 wchar_t *str2;
710 if (str != NULL) {
711 str2 = _PyMem_RawWcsdup(str);
712 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200713 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200714 }
715 }
716 else {
717 str2 = NULL;
718 }
719 PyMem_RawFree(*config_str);
720 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200721 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200722}
723
724
Victor Stinner331a6a52019-05-27 16:39:22 +0200725static PyStatus
726config_set_bytes_string(PyConfig *config, wchar_t **config_str,
727 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200728{
Victor Stinner331a6a52019-05-27 16:39:22 +0200729 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
730 if (_PyStatus_EXCEPTION(status)) {
731 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400732 }
733
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200734 wchar_t *str2;
735 if (str != NULL) {
736 size_t len;
737 str2 = Py_DecodeLocale(str, &len);
738 if (str2 == NULL) {
739 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200740 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200741 }
742 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200743 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200744 }
745 }
746 }
747 else {
748 str2 = NULL;
749 }
750 PyMem_RawFree(*config_str);
751 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200752 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200753}
754
755
Victor Stinner331a6a52019-05-27 16:39:22 +0200756#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
757 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400758
759
Victor Stinner70005ac2019-05-02 15:25:34 -0400760/* Decode str using Py_DecodeLocale() and set the result into *config_str.
761 Pre-initialize Python if needed to ensure that encodings are properly
762 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200763PyStatus
764PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200765 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400766{
Victor Stinner331a6a52019-05-27 16:39:22 +0200767 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400768}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200769
770
Victor Stinner331a6a52019-05-27 16:39:22 +0200771PyStatus
772_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200773{
Victor Stinner331a6a52019-05-27 16:39:22 +0200774 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200775
Victor Stinner331a6a52019-05-27 16:39:22 +0200776 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200777
778#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200779#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200780 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200781 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
782 if (_PyStatus_EXCEPTION(status)) { \
783 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200784 } \
785 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100786#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200787 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200788 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200789 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200790 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200791 } while (0)
792
Victor Stinner6d1c4672019-05-20 11:02:00 +0200793 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100794 COPY_ATTR(isolated);
795 COPY_ATTR(use_environment);
796 COPY_ATTR(dev_mode);
Victor Stinner1def7752020-04-23 03:03:24 +0200797 COPY_ATTR(_use_peg_parser);
Victor Stinner6c785c02018-08-01 17:56:14 +0200798 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200799 COPY_ATTR(use_hash_seed);
800 COPY_ATTR(hash_seed);
801 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200802 COPY_ATTR(faulthandler);
803 COPY_ATTR(tracemalloc);
804 COPY_ATTR(import_time);
805 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200806 COPY_ATTR(dump_refs);
807 COPY_ATTR(malloc_stats);
808
Victor Stinner124b9eb2018-08-29 01:29:06 +0200809 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200810 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200811 COPY_WSTR_ATTR(home);
812 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200813
Victor Stinnerae239f62019-05-16 17:02:56 +0200814 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100815 COPY_WSTRLIST(argv);
816 COPY_WSTRLIST(warnoptions);
817 COPY_WSTRLIST(xoptions);
818 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200819 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200820
Victor Stinner124b9eb2018-08-29 01:29:06 +0200821 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700822 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200823 COPY_WSTR_ATTR(prefix);
824 COPY_WSTR_ATTR(base_prefix);
825 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200826 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200827
Victor Stinner6c785c02018-08-01 17:56:14 +0200828 COPY_ATTR(site_import);
829 COPY_ATTR(bytes_warning);
830 COPY_ATTR(inspect);
831 COPY_ATTR(interactive);
832 COPY_ATTR(optimization_level);
833 COPY_ATTR(parser_debug);
834 COPY_ATTR(write_bytecode);
835 COPY_ATTR(verbose);
836 COPY_ATTR(quiet);
837 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200838 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200839 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400840 COPY_WSTR_ATTR(filesystem_encoding);
841 COPY_WSTR_ATTR(filesystem_errors);
842 COPY_WSTR_ATTR(stdio_encoding);
843 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200844#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200845 COPY_ATTR(legacy_windows_stdio);
846#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100847 COPY_ATTR(skip_source_first_line);
848 COPY_WSTR_ATTR(run_command);
849 COPY_WSTR_ATTR(run_module);
850 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400851 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200852 COPY_ATTR(pathconfig_warnings);
853 COPY_ATTR(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200854 COPY_ATTR(_isolated_interpreter);
Victor Stinner6c785c02018-08-01 17:56:14 +0200855
856#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200857#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200858#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200859 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200860}
861
862
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100863static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200864config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100865{
866 PyObject *dict;
867
868 dict = PyDict_New();
869 if (dict == NULL) {
870 return NULL;
871 }
872
873#define SET_ITEM(KEY, EXPR) \
874 do { \
875 PyObject *obj = (EXPR); \
876 if (obj == NULL) { \
877 goto fail; \
878 } \
879 int res = PyDict_SetItemString(dict, (KEY), obj); \
880 Py_DECREF(obj); \
881 if (res < 0) { \
882 goto fail; \
883 } \
884 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100885#define SET_ITEM_INT(ATTR) \
886 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
887#define SET_ITEM_UINT(ATTR) \
888 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100889#define FROM_WSTRING(STR) \
890 ((STR != NULL) ? \
891 PyUnicode_FromWideChar(STR, -1) \
892 : (Py_INCREF(Py_None), Py_None))
893#define SET_ITEM_WSTR(ATTR) \
894 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
895#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200896 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100897
Victor Stinner6d1c4672019-05-20 11:02:00 +0200898 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100899 SET_ITEM_INT(isolated);
900 SET_ITEM_INT(use_environment);
901 SET_ITEM_INT(dev_mode);
Victor Stinner1def7752020-04-23 03:03:24 +0200902 SET_ITEM_INT(_use_peg_parser);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100903 SET_ITEM_INT(install_signal_handlers);
904 SET_ITEM_INT(use_hash_seed);
905 SET_ITEM_UINT(hash_seed);
906 SET_ITEM_INT(faulthandler);
907 SET_ITEM_INT(tracemalloc);
908 SET_ITEM_INT(import_time);
909 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100910 SET_ITEM_INT(dump_refs);
911 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400912 SET_ITEM_WSTR(filesystem_encoding);
913 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100914 SET_ITEM_WSTR(pycache_prefix);
915 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200916 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100917 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100918 SET_ITEM_WSTRLIST(xoptions);
919 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200920 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100921 SET_ITEM_WSTR(home);
922 SET_ITEM_WSTRLIST(module_search_paths);
923 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700924 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100925 SET_ITEM_WSTR(prefix);
926 SET_ITEM_WSTR(base_prefix);
927 SET_ITEM_WSTR(exec_prefix);
928 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100929 SET_ITEM_INT(site_import);
930 SET_ITEM_INT(bytes_warning);
931 SET_ITEM_INT(inspect);
932 SET_ITEM_INT(interactive);
933 SET_ITEM_INT(optimization_level);
934 SET_ITEM_INT(parser_debug);
935 SET_ITEM_INT(write_bytecode);
936 SET_ITEM_INT(verbose);
937 SET_ITEM_INT(quiet);
938 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200939 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100940 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400941 SET_ITEM_WSTR(stdio_encoding);
942 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100943#ifdef MS_WINDOWS
944 SET_ITEM_INT(legacy_windows_stdio);
945#endif
946 SET_ITEM_INT(skip_source_first_line);
947 SET_ITEM_WSTR(run_command);
948 SET_ITEM_WSTR(run_module);
949 SET_ITEM_WSTR(run_filename);
950 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400951 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200952 SET_ITEM_INT(pathconfig_warnings);
953 SET_ITEM_INT(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200954 SET_ITEM_INT(_isolated_interpreter);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100955
956 return dict;
957
958fail:
959 Py_DECREF(dict);
960 return NULL;
961
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100962#undef FROM_WSTRING
963#undef SET_ITEM
964#undef SET_ITEM_INT
965#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100966#undef SET_ITEM_WSTR
967#undef SET_ITEM_WSTRLIST
968}
969
970
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100971static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200972config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200973{
Victor Stinner20004952019-03-26 02:31:11 +0100974 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200975}
976
977
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100978/* Get a copy of the environment variable as wchar_t*.
979 Return 0 on success, but *dest can be NULL.
980 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200981static PyStatus
982config_get_env_dup(PyConfig *config,
983 wchar_t **dest,
984 wchar_t *wname, char *name,
985 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200986{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200987 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100988 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200989
Victor Stinner20004952019-03-26 02:31:11 +0100990 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200991 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200992 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200993 }
994
995#ifdef MS_WINDOWS
996 const wchar_t *var = _wgetenv(wname);
997 if (!var || var[0] == '\0') {
998 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200999 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001000 }
1001
Victor Stinner331a6a52019-05-27 16:39:22 +02001002 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +02001003#else
1004 const char *var = getenv(name);
1005 if (!var || var[0] == '\0') {
1006 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001007 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001008 }
1009
Victor Stinner331a6a52019-05-27 16:39:22 +02001010 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001011#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001012}
1013
1014
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001015#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001016 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001017
1018
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001019static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001020config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001021{
Victor Stinner022be022019-05-22 23:58:50 +02001022 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1023 /* Python and Isolated configuration ignore global variables */
1024 return;
1025 }
1026
Victor Stinner6c785c02018-08-01 17:56:14 +02001027#define COPY_FLAG(ATTR, VALUE) \
1028 if (config->ATTR == -1) { \
1029 config->ATTR = VALUE; \
1030 }
1031#define COPY_NOT_FLAG(ATTR, VALUE) \
1032 if (config->ATTR == -1) { \
1033 config->ATTR = !(VALUE); \
1034 }
1035
Victor Stinner20004952019-03-26 02:31:11 +01001036 COPY_FLAG(isolated, Py_IsolatedFlag);
1037 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001038 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1039 COPY_FLAG(inspect, Py_InspectFlag);
1040 COPY_FLAG(interactive, Py_InteractiveFlag);
1041 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1042 COPY_FLAG(parser_debug, Py_DebugFlag);
1043 COPY_FLAG(verbose, Py_VerboseFlag);
1044 COPY_FLAG(quiet, Py_QuietFlag);
1045#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001046 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1047#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001048 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001049
Victor Stinner6c785c02018-08-01 17:56:14 +02001050 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1051 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1052 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1053 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1054
Victor Stinner6c785c02018-08-01 17:56:14 +02001055#undef COPY_FLAG
1056#undef COPY_NOT_FLAG
1057}
1058
1059
1060/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001061static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001062config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001063{
1064#define COPY_FLAG(ATTR, VAR) \
1065 if (config->ATTR != -1) { \
1066 VAR = config->ATTR; \
1067 }
1068#define COPY_NOT_FLAG(ATTR, VAR) \
1069 if (config->ATTR != -1) { \
1070 VAR = !config->ATTR; \
1071 }
1072
Victor Stinner20004952019-03-26 02:31:11 +01001073 COPY_FLAG(isolated, Py_IsolatedFlag);
1074 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001075 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1076 COPY_FLAG(inspect, Py_InspectFlag);
1077 COPY_FLAG(interactive, Py_InteractiveFlag);
1078 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1079 COPY_FLAG(parser_debug, Py_DebugFlag);
1080 COPY_FLAG(verbose, Py_VerboseFlag);
1081 COPY_FLAG(quiet, Py_QuietFlag);
1082#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001083 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1084#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001085 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001086
Victor Stinner6c785c02018-08-01 17:56:14 +02001087 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1088 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1089 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1090 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1091
Victor Stinner6c785c02018-08-01 17:56:14 +02001092 /* Random or non-zero hash seed */
1093 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1094 config->hash_seed != 0);
1095
1096#undef COPY_FLAG
1097#undef COPY_NOT_FLAG
1098}
1099
1100
1101/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1102 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001103static PyStatus
1104config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001105{
Victor Stinner331a6a52019-05-27 16:39:22 +02001106 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001107
Victor Stinner6c785c02018-08-01 17:56:14 +02001108 /* If Py_SetProgramName() was called, use its value */
1109 const wchar_t *program_name = _Py_path_config.program_name;
1110 if (program_name != NULL) {
1111 config->program_name = _PyMem_RawWcsdup(program_name);
1112 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001113 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001114 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001115 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001116 }
1117
1118#ifdef __APPLE__
1119 /* On MacOS X, when the Python interpreter is embedded in an
1120 application bundle, it gets executed by a bootstrapping script
1121 that does os.execve() with an argv[0] that's different from the
1122 actual Python executable. This is needed to keep the Finder happy,
1123 or rather, to work around Apple's overly strict requirements of
1124 the process name. However, we still need a usable sys.executable,
1125 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001126 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001127 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001128 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001129 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001130 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1131 "PYTHONEXECUTABLE environment variable");
1132 if (_PyStatus_EXCEPTION(status)) {
1133 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001134 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001135 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001136 }
1137#ifdef WITH_NEXT_FRAMEWORK
1138 else {
1139 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1140 if (pyvenv_launcher && *pyvenv_launcher) {
1141 /* Used by Mac/Tools/pythonw.c to forward
1142 * the argv0 of the stub executable
1143 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001144 status = CONFIG_SET_BYTES_STR(config,
1145 &config->program_name,
1146 pyvenv_launcher,
1147 "__PYVENV_LAUNCHER__ environment variable");
1148 if (_PyStatus_EXCEPTION(status)) {
1149 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001150 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001151
1152 /*
1153 * This environment variable is used to communicate between
1154 * the stub launcher and the real interpreter and isn't needed
1155 * beyond this point.
1156 *
1157 * Clean up to avoid problems when launching other programs
1158 * later on.
1159 */
1160 (void)unsetenv("__PYVENV_LAUNCHER__");
1161
Victor Stinner331a6a52019-05-27 16:39:22 +02001162 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001163 }
1164 }
1165#endif /* WITH_NEXT_FRAMEWORK */
1166#endif /* __APPLE__ */
1167
Victor Stinnerfed02e12019-05-17 11:12:09 +02001168 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001169 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001170 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1171 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1172 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001173 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001174 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001175 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001176 }
1177
Victor Stinnerfed02e12019-05-17 11:12:09 +02001178 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001179#ifdef MS_WINDOWS
1180 const wchar_t *default_program_name = L"python";
1181#else
1182 const wchar_t *default_program_name = L"python3";
1183#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001184 status = PyConfig_SetString(config, &config->program_name,
1185 default_program_name);
1186 if (_PyStatus_EXCEPTION(status)) {
1187 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001188 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001189 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001190}
1191
Victor Stinner331a6a52019-05-27 16:39:22 +02001192static PyStatus
1193config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001194{
1195 assert(config->executable == NULL);
1196
1197 /* If Py_SetProgramFullPath() was called, use its value */
1198 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1199 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001200 PyStatus status = PyConfig_SetString(config,
1201 &config->executable,
1202 program_full_path);
1203 if (_PyStatus_EXCEPTION(status)) {
1204 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001205 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001206 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001207 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001208 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001209}
Victor Stinner6c785c02018-08-01 17:56:14 +02001210
Victor Stinner4fffd382019-03-06 01:44:31 +01001211
Victor Stinner6c785c02018-08-01 17:56:14 +02001212static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001213config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001214{
Victor Stinner74f65682019-03-15 15:08:05 +01001215 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001216}
1217
1218
Victor Stinner331a6a52019-05-27 16:39:22 +02001219static PyStatus
1220config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001221{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001222 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001223
1224 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001225 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001226 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001227 PyStatus status = PyConfig_SetString(config, &config->home, home);
1228 if (_PyStatus_EXCEPTION(status)) {
1229 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001230 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001231 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001232 }
1233
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001234 return CONFIG_GET_ENV_DUP(config, &config->home,
1235 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001236}
1237
1238
Victor Stinner331a6a52019-05-27 16:39:22 +02001239static PyStatus
1240config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001241{
Victor Stinner331a6a52019-05-27 16:39:22 +02001242 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001243
1244 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1245 /* Convert a text seed to a numeric one */
1246 if (seed_text && strcmp(seed_text, "random") != 0) {
1247 const char *endptr = seed_text;
1248 unsigned long seed;
1249 errno = 0;
1250 seed = strtoul(seed_text, (char **)&endptr, 10);
1251 if (*endptr != '\0'
1252 || seed > 4294967295UL
1253 || (errno == ERANGE && seed == ULONG_MAX))
1254 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001255 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001256 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001257 }
1258 /* Use a specific hash */
1259 config->use_hash_seed = 1;
1260 config->hash_seed = seed;
1261 }
1262 else {
1263 /* Use a random hash */
1264 config->use_hash_seed = 0;
1265 config->hash_seed = 0;
1266 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001267 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001268}
1269
1270
Victor Stinner6c785c02018-08-01 17:56:14 +02001271static int
1272config_wstr_to_int(const wchar_t *wstr, int *result)
1273{
1274 const wchar_t *endptr = wstr;
1275 errno = 0;
1276 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1277 if (*endptr != '\0' || errno == ERANGE) {
1278 return -1;
1279 }
1280 if (value < INT_MIN || value > INT_MAX) {
1281 return -1;
1282 }
1283
1284 *result = (int)value;
1285 return 0;
1286}
1287
1288
Victor Stinner331a6a52019-05-27 16:39:22 +02001289static PyStatus
1290config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001291{
Victor Stinner331a6a52019-05-27 16:39:22 +02001292 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001293 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001294
Victor Stinner6c785c02018-08-01 17:56:14 +02001295 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001296 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1297 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1298 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1299 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001300
1301 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001302 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001303 if (dont_write_bytecode) {
1304 config->write_bytecode = 0;
1305 }
1306
1307 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001308 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001309 if (no_user_site_directory) {
1310 config->user_site_directory = 0;
1311 }
1312
1313 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001314 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001315 if (unbuffered_stdio) {
1316 config->buffered_stdio = 0;
1317 }
1318
1319#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001320 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001321 "PYTHONLEGACYWINDOWSSTDIO");
1322#endif
1323
Victor Stinner331a6a52019-05-27 16:39:22 +02001324 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001325 config->dump_refs = 1;
1326 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001327 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001328 config->malloc_stats = 1;
1329 }
1330
Victor Stinner331a6a52019-05-27 16:39:22 +02001331 if (config->pythonpath_env == NULL) {
1332 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1333 L"PYTHONPATH", "PYTHONPATH");
1334 if (_PyStatus_EXCEPTION(status)) {
1335 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001336 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001337 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001338
1339 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001340 status = config_init_hash_seed(config);
1341 if (_PyStatus_EXCEPTION(status)) {
1342 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001343 }
1344 }
1345
Victor Stinner331a6a52019-05-27 16:39:22 +02001346 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001347}
1348
1349
Victor Stinner331a6a52019-05-27 16:39:22 +02001350static PyStatus
1351config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001352{
1353 int nframe;
1354 int valid;
1355
Victor Stinner331a6a52019-05-27 16:39:22 +02001356 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001357 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001358 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001359 valid = (nframe >= 0);
1360 }
1361 else {
1362 valid = 0;
1363 }
1364 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001365 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001366 }
1367 config->tracemalloc = nframe;
1368 }
1369
1370 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1371 if (xoption) {
1372 const wchar_t *sep = wcschr(xoption, L'=');
1373 if (sep) {
1374 if (!config_wstr_to_int(sep + 1, &nframe)) {
1375 valid = (nframe >= 0);
1376 }
1377 else {
1378 valid = 0;
1379 }
1380 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001381 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1382 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001383 }
1384 }
1385 else {
1386 /* -X tracemalloc behaves as -X tracemalloc=1 */
1387 nframe = 1;
1388 }
1389 config->tracemalloc = nframe;
1390 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001391 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001392}
1393
1394
Victor Stinner331a6a52019-05-27 16:39:22 +02001395static PyStatus
1396config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001397{
1398 assert(config->pycache_prefix == NULL);
1399
1400 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1401 if (xoption) {
1402 const wchar_t *sep = wcschr(xoption, L'=');
1403 if (sep && wcslen(sep) > 1) {
1404 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1405 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001406 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001407 }
1408 }
1409 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001410 // PYTHONPYCACHEPREFIX env var ignored
1411 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001412 config->pycache_prefix = NULL;
1413 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001414 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001415 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001416
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001417 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1418 L"PYTHONPYCACHEPREFIX",
1419 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001420}
1421
1422
Victor Stinner331a6a52019-05-27 16:39:22 +02001423static PyStatus
1424config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001425{
1426 /* More complex options configured by env var and -X option */
1427 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001428 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001429 || config_get_xoption(config, L"faulthandler")) {
1430 config->faulthandler = 1;
1431 }
1432 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001433 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001434 || config_get_xoption(config, L"importtime")) {
1435 config->import_time = 1;
1436 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001437
Pablo Galindoc5fc1562020-04-22 23:29:27 +01001438 if (config_get_env(config, "PYTHONOLDPARSER")
1439 || config_get_xoption(config, L"oldparser")) {
Victor Stinner1def7752020-04-23 03:03:24 +02001440 config->_use_peg_parser = 0;
Pablo Galindoc5fc1562020-04-22 23:29:27 +01001441 }
1442
Victor Stinner331a6a52019-05-27 16:39:22 +02001443 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001444 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001445 status = config_init_tracemalloc(config);
1446 if (_PyStatus_EXCEPTION(status)) {
1447 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001448 }
1449 }
1450
1451 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001452 status = config_init_pycache_prefix(config);
1453 if (_PyStatus_EXCEPTION(status)) {
1454 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001455 }
1456 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001457 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001458}
1459
1460
Victor Stinner709d23d2019-05-02 14:56:30 -04001461static const wchar_t *
Andy Lesteraa450a02020-03-07 11:36:04 -06001462config_get_stdio_errors(void)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001463{
1464#ifndef MS_WINDOWS
1465 const char *loc = setlocale(LC_CTYPE, NULL);
1466 if (loc != NULL) {
1467 /* surrogateescape is the default in the legacy C and POSIX locales */
1468 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001469 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001470 }
1471
1472#ifdef PY_COERCE_C_LOCALE
1473 /* surrogateescape is the default in locale coercion target locales */
1474 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001475 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001476 }
1477#endif
1478 }
1479
Victor Stinner709d23d2019-05-02 14:56:30 -04001480 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001481#else
1482 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001483 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001484#endif
1485}
1486
1487
Victor Stinner331a6a52019-05-27 16:39:22 +02001488static PyStatus
1489config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001490{
1491#ifdef MS_WINDOWS
1492 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001493 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001494 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001495#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001496 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001497#else
1498 const char *encoding = nl_langinfo(CODESET);
1499 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001500 return _PyStatus_ERR("failed to get the locale encoding: "
1501 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001502 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001503 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001504 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001505 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001506 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001507#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001508}
1509
1510
Victor Stinner331a6a52019-05-27 16:39:22 +02001511static PyStatus
1512config_init_stdio_encoding(PyConfig *config,
1513 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001514{
Victor Stinner331a6a52019-05-27 16:39:22 +02001515 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001516
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001517 /* If Py_SetStandardStreamEncoding() have been called, use these
1518 parameters. */
1519 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001520 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1521 _Py_StandardStreamEncoding,
1522 "_Py_StandardStreamEncoding");
1523 if (_PyStatus_EXCEPTION(status)) {
1524 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001525 }
1526 }
1527
1528 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001529 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1530 _Py_StandardStreamErrors,
1531 "_Py_StandardStreamErrors");
1532 if (_PyStatus_EXCEPTION(status)) {
1533 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001534 }
1535 }
1536
1537 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001538 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001539 }
1540
1541 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001542 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001543 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001544 char *pythonioencoding = _PyMem_RawStrdup(opt);
1545 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001546 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001547 }
1548
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001549 char *errors = strchr(pythonioencoding, ':');
1550 if (errors) {
1551 *errors = '\0';
1552 errors++;
1553 if (!errors[0]) {
1554 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001555 }
1556 }
1557
1558 /* Does PYTHONIOENCODING contain an encoding? */
1559 if (pythonioencoding[0]) {
1560 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001561 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1562 pythonioencoding,
1563 "PYTHONIOENCODING environment variable");
1564 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001565 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001566 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001567 }
1568 }
1569
1570 /* If the encoding is set but not the error handler,
1571 use "strict" error handler by default.
1572 PYTHONIOENCODING=latin1 behaves as
1573 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001574 if (!errors) {
1575 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001576 }
1577 }
1578
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001579 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001580 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1581 errors,
1582 "PYTHONIOENCODING environment variable");
1583 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001584 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001585 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001586 }
1587 }
1588
1589 PyMem_RawFree(pythonioencoding);
1590 }
1591
1592 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001593 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001594 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001595 status = PyConfig_SetString(config, &config->stdio_encoding,
1596 L"utf-8");
1597 if (_PyStatus_EXCEPTION(status)) {
1598 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001599 }
1600 }
1601 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001602 status = PyConfig_SetString(config, &config->stdio_errors,
1603 L"surrogateescape");
1604 if (_PyStatus_EXCEPTION(status)) {
1605 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001606 }
1607 }
1608 }
1609
1610 /* Choose the default error handler based on the current locale. */
1611 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001612 status = config_get_locale_encoding(config, &config->stdio_encoding);
1613 if (_PyStatus_EXCEPTION(status)) {
1614 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001615 }
1616 }
1617 if (config->stdio_errors == NULL) {
Andy Lesteraa450a02020-03-07 11:36:04 -06001618 const wchar_t *errors = config_get_stdio_errors();
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001619 assert(errors != NULL);
1620
Victor Stinner331a6a52019-05-27 16:39:22 +02001621 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1622 if (_PyStatus_EXCEPTION(status)) {
1623 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001624 }
1625 }
1626
Victor Stinner331a6a52019-05-27 16:39:22 +02001627 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001628}
1629
1630
Victor Stinner331a6a52019-05-27 16:39:22 +02001631static PyStatus
1632config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001633{
Victor Stinner331a6a52019-05-27 16:39:22 +02001634 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001635
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001636 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001637#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001638 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001639#else
Victor Stinnere2510952019-05-02 11:28:57 -04001640
1641#ifdef MS_WINDOWS
1642 if (preconfig->legacy_windows_fs_encoding) {
1643 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001644 status = PyConfig_SetString(config, &config->filesystem_encoding,
1645 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001646 }
1647 else
1648#endif
Victor Stinner20004952019-03-26 02:31:11 +01001649 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001650 status = PyConfig_SetString(config, &config->filesystem_encoding,
1651 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001652 }
Victor Stinnere2510952019-05-02 11:28:57 -04001653#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001654 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001655 status = PyConfig_SetString(config, &config->filesystem_encoding,
1656 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001657 }
Victor Stinnere2510952019-05-02 11:28:57 -04001658#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001659 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001660#ifdef MS_WINDOWS
1661 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001662 status = PyConfig_SetString(config, &config->filesystem_encoding,
1663 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001664#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001665 status = config_get_locale_encoding(config,
1666 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001667#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001668 }
Victor Stinnere2510952019-05-02 11:28:57 -04001669#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001670
Victor Stinner331a6a52019-05-27 16:39:22 +02001671 if (_PyStatus_EXCEPTION(status)) {
1672 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001673 }
1674 }
1675
1676 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001677 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001678#ifdef MS_WINDOWS
1679 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001680 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001681 }
1682 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001683 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001684 }
1685#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001686 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001687#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001688 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1689 if (_PyStatus_EXCEPTION(status)) {
1690 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001691 }
1692 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001693 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001694}
1695
1696
Victor Stinner331a6a52019-05-27 16:39:22 +02001697static PyStatus
1698config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001699{
Victor Stinner331a6a52019-05-27 16:39:22 +02001700 PyStatus status;
1701 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001702
Victor Stinner20004952019-03-26 02:31:11 +01001703 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001704 status = config_read_env_vars(config);
1705 if (_PyStatus_EXCEPTION(status)) {
1706 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001707 }
1708 }
1709
1710 /* -X options */
1711 if (config_get_xoption(config, L"showrefcount")) {
1712 config->show_ref_count = 1;
1713 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001714
Victor Stinner331a6a52019-05-27 16:39:22 +02001715 status = config_read_complex_options(config);
1716 if (_PyStatus_EXCEPTION(status)) {
1717 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001718 }
1719
Victor Stinner6c785c02018-08-01 17:56:14 +02001720 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001721 status = config_init_home(config);
1722 if (_PyStatus_EXCEPTION(status)) {
1723 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001724 }
1725 }
1726
Steve Dower177a41a2018-11-17 20:41:48 -08001727 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001728 status = config_init_executable(config);
1729 if (_PyStatus_EXCEPTION(status)) {
1730 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001731 }
1732 }
1733
Victor Stinner6c785c02018-08-01 17:56:14 +02001734 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001735 status = _PyConfig_InitPathConfig(config);
1736 if (_PyStatus_EXCEPTION(status)) {
1737 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001738 }
1739 }
1740
1741 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001742 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001743 if (config->faulthandler < 0) {
1744 config->faulthandler = 1;
1745 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001746 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001747 if (config->faulthandler < 0) {
1748 config->faulthandler = 0;
1749 }
1750 if (config->tracemalloc < 0) {
1751 config->tracemalloc = 0;
1752 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001753 if (config->use_hash_seed < 0) {
1754 config->use_hash_seed = 0;
1755 config->hash_seed = 0;
1756 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001757
Victor Stinner70fead22018-08-29 13:45:34 +02001758 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001759 status = config_init_fs_encoding(config, preconfig);
1760 if (_PyStatus_EXCEPTION(status)) {
1761 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001762 }
1763 }
1764
Victor Stinner331a6a52019-05-27 16:39:22 +02001765 status = config_init_stdio_encoding(config, preconfig);
1766 if (_PyStatus_EXCEPTION(status)) {
1767 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001768 }
1769
Victor Stinner62599762019-03-15 16:03:23 +01001770 if (config->argv.length < 1) {
1771 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001772 status = PyWideStringList_Append(&config->argv, L"");
1773 if (_PyStatus_EXCEPTION(status)) {
1774 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001775 }
1776 }
Victor Stinner870b0352019-05-17 03:15:12 +02001777
1778 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001779 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1780 L"default");
1781 if (_PyStatus_EXCEPTION(status)) {
1782 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001783 }
1784 }
1785
1786 if (config->configure_c_stdio < 0) {
1787 config->configure_c_stdio = 1;
1788 }
1789
Victor Stinner331a6a52019-05-27 16:39:22 +02001790 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001791}
Victor Stinner5ed69952018-11-06 15:59:52 +01001792
1793
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001794static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001795config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001796{
1797#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1798 /* don't translate newlines (\r\n <=> \n) */
1799 _setmode(fileno(stdin), O_BINARY);
1800 _setmode(fileno(stdout), O_BINARY);
1801 _setmode(fileno(stderr), O_BINARY);
1802#endif
1803
1804 if (!config->buffered_stdio) {
1805#ifdef HAVE_SETVBUF
1806 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1807 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1808 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1809#else /* !HAVE_SETVBUF */
1810 setbuf(stdin, (char *)NULL);
1811 setbuf(stdout, (char *)NULL);
1812 setbuf(stderr, (char *)NULL);
1813#endif /* !HAVE_SETVBUF */
1814 }
1815 else if (config->interactive) {
1816#ifdef MS_WINDOWS
1817 /* Doesn't have to have line-buffered -- use unbuffered */
1818 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1819 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1820#else /* !MS_WINDOWS */
1821#ifdef HAVE_SETVBUF
1822 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1823 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1824#endif /* HAVE_SETVBUF */
1825#endif /* !MS_WINDOWS */
1826 /* Leave stderr alone - it should be unbuffered anyway. */
1827 }
1828}
1829
1830
1831/* Write the configuration:
1832
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001833 - set Py_xxx global configuration variables
1834 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001835void
Victor Stinner331a6a52019-05-27 16:39:22 +02001836_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001837{
Victor Stinner331a6a52019-05-27 16:39:22 +02001838 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001839
1840 if (config->configure_c_stdio) {
1841 config_init_stdio(config);
1842 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001843
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001844 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001845 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001846 preconfig->isolated = config->isolated;
1847 preconfig->use_environment = config->use_environment;
1848 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001849}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001850
1851
Victor Stinner331a6a52019-05-27 16:39:22 +02001852/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001853
1854static void
Victor Stinner2f549082019-03-29 15:13:46 +01001855config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001856{
Victor Stinner2f549082019-03-29 15:13:46 +01001857 FILE *f = error ? stderr : stdout;
1858
1859 fprintf(f, usage_line, program);
1860 if (error)
1861 fprintf(f, "Try `python -h' for more information.\n");
1862 else {
1863 fputs(usage_1, f);
1864 fputs(usage_2, f);
1865 fputs(usage_3, f);
1866 fprintf(f, usage_4, (wint_t)DELIM);
1867 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1868 fputs(usage_6, f);
1869 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001870}
1871
1872
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001873/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001874static PyStatus
1875config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001876 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001877{
Victor Stinner331a6a52019-05-27 16:39:22 +02001878 PyStatus status;
1879 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001880 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001881 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001882
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001883 _PyOS_ResetGetOpt();
1884 do {
1885 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001886 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001887 if (c == EOF) {
1888 break;
1889 }
1890
1891 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001892 if (config->run_command == NULL) {
1893 /* -c is the last option; following arguments
1894 that look like options are left for the
1895 command to interpret. */
1896 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1897 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1898 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001899 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001900 }
1901 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1902 command[len - 2] = '\n';
1903 command[len - 1] = 0;
1904 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001905 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001906 break;
1907 }
1908
1909 if (c == 'm') {
1910 /* -m is the last option; following arguments
1911 that look like options are left for the
1912 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001913 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001914 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1915 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001916 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001917 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001918 }
1919 break;
1920 }
1921
1922 switch (c) {
1923 case 0:
1924 // Handle long option.
1925 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001926 if (wcscmp(_PyOS_optarg, L"always") == 0
1927 || wcscmp(_PyOS_optarg, L"never") == 0
1928 || wcscmp(_PyOS_optarg, L"default") == 0)
1929 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001930 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1931 _PyOS_optarg);
1932 if (_PyStatus_EXCEPTION(status)) {
1933 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001934 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001935 } else {
1936 fprintf(stderr, "--check-hash-based-pycs must be one of "
1937 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001938 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001939 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001940 }
1941 break;
1942
1943 case 'b':
1944 config->bytes_warning++;
1945 break;
1946
1947 case 'd':
1948 config->parser_debug++;
1949 break;
1950
1951 case 'i':
1952 config->inspect++;
1953 config->interactive++;
1954 break;
1955
Victor Stinner6dcb5422019-03-05 02:44:12 +01001956 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001957 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001958 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001959 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001960 break;
1961
1962 /* case 'J': reserved for Jython */
1963
1964 case 'O':
1965 config->optimization_level++;
1966 break;
1967
1968 case 'B':
1969 config->write_bytecode = 0;
1970 break;
1971
1972 case 's':
1973 config->user_site_directory = 0;
1974 break;
1975
1976 case 'S':
1977 config->site_import = 0;
1978 break;
1979
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001980 case 't':
1981 /* ignored for backwards compatibility */
1982 break;
1983
1984 case 'u':
1985 config->buffered_stdio = 0;
1986 break;
1987
1988 case 'v':
1989 config->verbose++;
1990 break;
1991
1992 case 'x':
1993 config->skip_source_first_line = 1;
1994 break;
1995
1996 case 'h':
1997 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001998 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001999 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002000
2001 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01002002 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002003 break;
2004
2005 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002006 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2007 if (_PyStatus_EXCEPTION(status)) {
2008 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002009 }
2010 break;
2011
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002012 case 'q':
2013 config->quiet++;
2014 break;
2015
2016 case 'R':
2017 config->use_hash_seed = 0;
2018 break;
2019
2020 /* This space reserved for other options */
2021
2022 default:
2023 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002024 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002025 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002026 }
2027 } while (1);
2028
Victor Stinner2f549082019-03-29 15:13:46 +01002029 if (print_version) {
2030 printf("Python %s\n",
2031 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002032 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002033 }
2034
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002035 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002036 && _PyOS_optind < argv->length
2037 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002038 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002039 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002040 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002041 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002042 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002043 }
2044 }
2045
2046 if (config->run_command != NULL || config->run_module != NULL) {
2047 /* Backup _PyOS_optind */
2048 _PyOS_optind--;
2049 }
2050
Victor Stinnerae239f62019-05-16 17:02:56 +02002051 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002052
Victor Stinner331a6a52019-05-27 16:39:22 +02002053 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002054}
2055
2056
2057#ifdef MS_WINDOWS
2058# define WCSTOK wcstok_s
2059#else
2060# define WCSTOK wcstok
2061#endif
2062
2063/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002064static PyStatus
2065config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002066{
Victor Stinner331a6a52019-05-27 16:39:22 +02002067 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002068 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2069 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002070 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002071 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002072 if (_PyStatus_EXCEPTION(status)) {
2073 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002074 }
2075
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002076 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002077 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002078 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002079 }
2080
2081
2082 wchar_t *warning, *context = NULL;
2083 for (warning = WCSTOK(env, L",", &context);
2084 warning != NULL;
2085 warning = WCSTOK(NULL, L",", &context))
2086 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002087 status = PyWideStringList_Append(warnoptions, warning);
2088 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002089 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002090 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002091 }
2092 }
2093 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002094 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002095}
2096
2097
Victor Stinner331a6a52019-05-27 16:39:22 +02002098static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002099warnoptions_append(PyConfig *config, PyWideStringList *options,
2100 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002101{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002102 /* config_init_warnoptions() add existing config warnoptions at the end:
2103 ensure that the new option is not already present in this list to
2104 prevent change the options order whne config_init_warnoptions() is
2105 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002106 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002107 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002108 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002109 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002110 if (_PyWideStringList_Find(options, option)) {
2111 /* Already present: do nothing */
2112 return _PyStatus_OK();
2113 }
2114 return PyWideStringList_Append(options, option);
2115}
2116
2117
2118static PyStatus
2119warnoptions_extend(PyConfig *config, PyWideStringList *options,
2120 const PyWideStringList *options2)
2121{
2122 const Py_ssize_t len = options2->length;
2123 wchar_t *const *items = options2->items;
2124
2125 for (Py_ssize_t i = 0; i < len; i++) {
2126 PyStatus status = warnoptions_append(config, options, items[i]);
2127 if (_PyStatus_EXCEPTION(status)) {
2128 return status;
2129 }
2130 }
2131 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002132}
2133
2134
Victor Stinner331a6a52019-05-27 16:39:22 +02002135static PyStatus
2136config_init_warnoptions(PyConfig *config,
2137 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002138 const PyWideStringList *env_warnoptions,
2139 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002140{
Victor Stinner331a6a52019-05-27 16:39:22 +02002141 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002142 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002143
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002144 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002145 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002146 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002147 * - PyConfig.dev_mode: "default" filter
2148 * - PYTHONWARNINGS environment variable
2149 * - '-W' command line options
2150 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2151 * "default::BytesWarning" or "error::BytesWarning" filter
2152 * - early PySys_AddWarnOption() calls
2153 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002154 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002155 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2156 * module works on the basis of "the most recently added filter will be
2157 * checked first", we add the lowest precedence entries first so that later
2158 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002159 */
2160
Victor Stinner20004952019-03-26 02:31:11 +01002161 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002162 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002163 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002164 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002165 }
2166 }
2167
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002168 status = warnoptions_extend(config, &options, env_warnoptions);
2169 if (_PyStatus_EXCEPTION(status)) {
2170 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002171 }
2172
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002173 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2174 if (_PyStatus_EXCEPTION(status)) {
2175 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002176 }
2177
2178 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2179 * don't even try to emit a warning, so we skip setting the filter in that
2180 * case.
2181 */
2182 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002183 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002184 if (config->bytes_warning> 1) {
2185 filter = L"error::BytesWarning";
2186 }
2187 else {
2188 filter = L"default::BytesWarning";
2189 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002190 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002191 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002192 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002193 }
2194 }
Victor Stinner120b7072019-08-23 18:03:08 +01002195
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002196 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002197 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002198 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002199 }
2200
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002201 /* Always add all PyConfig.warnoptions options */
2202 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2203 if (_PyStatus_EXCEPTION(status)) {
2204 goto error;
2205 }
2206
2207 _PyWideStringList_Clear(&config->warnoptions);
2208 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002209 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002210
2211error:
2212 _PyWideStringList_Clear(&options);
2213 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002214}
2215
2216
Victor Stinner331a6a52019-05-27 16:39:22 +02002217static PyStatus
2218config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002219{
Victor Stinner331a6a52019-05-27 16:39:22 +02002220 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002221 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002222
Victor Stinner74f65682019-03-15 15:08:05 +01002223 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002224 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002225 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002226 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2227 if (_PyStatus_EXCEPTION(status)) {
2228 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002229 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002230 }
2231 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002232 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002233 slice.length = cmdline_argv->length - opt_index;
2234 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002235 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2236 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002237 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002238 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002239 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002240
2241 wchar_t *arg0 = NULL;
2242 if (config->run_command != NULL) {
2243 /* Force sys.argv[0] = '-c' */
2244 arg0 = L"-c";
2245 }
2246 else if (config->run_module != NULL) {
2247 /* Force sys.argv[0] = '-m'*/
2248 arg0 = L"-m";
2249 }
Victor Stinner3939c322019-06-25 15:02:43 +02002250
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002251 if (arg0 != NULL) {
2252 arg0 = _PyMem_RawWcsdup(arg0);
2253 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002254 _PyWideStringList_Clear(&config_argv);
2255 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002256 }
2257
Victor Stinnerfa153762019-03-20 04:25:38 +01002258 PyMem_RawFree(config_argv.items[0]);
2259 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002260 }
2261
Victor Stinner331a6a52019-05-27 16:39:22 +02002262 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002263 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002264 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002265}
2266
2267
Victor Stinner331a6a52019-05-27 16:39:22 +02002268static PyStatus
2269core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002270{
Victor Stinner331a6a52019-05-27 16:39:22 +02002271 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002272
Victor Stinnercab5d072019-05-17 19:01:14 +02002273 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002274 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2275 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002276 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002277 }
2278
Victor Stinner331a6a52019-05-27 16:39:22 +02002279 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002280
2281 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2282 if (_PyStatus_EXCEPTION(status)) {
2283 return status;
2284 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002285
Victor Stinner331a6a52019-05-27 16:39:22 +02002286 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002287
Victor Stinner331a6a52019-05-27 16:39:22 +02002288 status = _PyPreCmdline_Read(precmdline, &preconfig);
2289 if (_PyStatus_EXCEPTION(status)) {
2290 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002291 }
2292
Victor Stinner331a6a52019-05-27 16:39:22 +02002293 status = _PyPreCmdline_SetConfig(precmdline, config);
2294 if (_PyStatus_EXCEPTION(status)) {
2295 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002296 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002297 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002298}
2299
2300
Victor Stinner3939c322019-06-25 15:02:43 +02002301/* Get run_filename absolute path */
2302static PyStatus
2303config_run_filename_abspath(PyConfig *config)
2304{
2305 if (!config->run_filename) {
2306 return _PyStatus_OK();
2307 }
2308
2309#ifndef MS_WINDOWS
2310 if (_Py_isabs(config->run_filename)) {
2311 /* path is already absolute */
2312 return _PyStatus_OK();
2313 }
2314#endif
2315
2316 wchar_t *abs_filename;
2317 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2318 /* failed to get the absolute path of the command line filename:
2319 ignore the error, keep the relative path */
2320 return _PyStatus_OK();
2321 }
2322 if (abs_filename == NULL) {
2323 return _PyStatus_NO_MEMORY();
2324 }
2325
2326 PyMem_RawFree(config->run_filename);
2327 config->run_filename = abs_filename;
2328 return _PyStatus_OK();
2329}
2330
2331
Victor Stinner331a6a52019-05-27 16:39:22 +02002332static PyStatus
2333config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002334{
Victor Stinner331a6a52019-05-27 16:39:22 +02002335 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002336 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2337 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2338 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002339
Victor Stinnerae239f62019-05-16 17:02:56 +02002340 if (config->parse_argv < 0) {
2341 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002342 }
Victor Stinner870b0352019-05-17 03:15:12 +02002343
Victor Stinnerfed02e12019-05-17 11:12:09 +02002344 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002345 status = config_init_program_name(config);
2346 if (_PyStatus_EXCEPTION(status)) {
2347 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002348 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002349 }
Victor Stinner2f549082019-03-29 15:13:46 +01002350
Victor Stinnerae239f62019-05-16 17:02:56 +02002351 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002352 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002353 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2354 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002355 goto done;
2356 }
2357
Victor Stinner3939c322019-06-25 15:02:43 +02002358 status = config_run_filename_abspath(config);
2359 if (_PyStatus_EXCEPTION(status)) {
2360 goto done;
2361 }
2362
Victor Stinner331a6a52019-05-27 16:39:22 +02002363 status = config_update_argv(config, opt_index);
2364 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002365 goto done;
2366 }
Victor Stinner2f549082019-03-29 15:13:46 +01002367 }
Victor Stinner3939c322019-06-25 15:02:43 +02002368 else {
2369 status = config_run_filename_abspath(config);
2370 if (_PyStatus_EXCEPTION(status)) {
2371 goto done;
2372 }
2373 }
Victor Stinner2f549082019-03-29 15:13:46 +01002374
Victor Stinner2f549082019-03-29 15:13:46 +01002375 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002376 status = config_init_env_warnoptions(config, &env_warnoptions);
2377 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002378 goto done;
2379 }
2380 }
2381
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002382 /* Handle early PySys_AddWarnOption() calls */
2383 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2384 if (_PyStatus_EXCEPTION(status)) {
2385 goto done;
2386 }
2387
Victor Stinner331a6a52019-05-27 16:39:22 +02002388 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002389 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002390 &env_warnoptions,
2391 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002392 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002393 goto done;
2394 }
2395
Victor Stinner331a6a52019-05-27 16:39:22 +02002396 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002397
2398done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002399 _PyWideStringList_Clear(&cmdline_warnoptions);
2400 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002401 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002402 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002403}
2404
2405
Victor Stinner331a6a52019-05-27 16:39:22 +02002406PyStatus
2407_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002408{
Victor Stinner331a6a52019-05-27 16:39:22 +02002409 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2410 if (_PyStatus_EXCEPTION(status)) {
2411 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002412 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002413
Victor Stinner5f38b842019-05-01 02:30:12 +02002414 return _PyArgv_AsWstrList(args, &config->argv);
2415}
2416
2417
Victor Stinner70005ac2019-05-02 15:25:34 -04002418/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2419 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002420PyStatus
2421PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002422{
2423 _PyArgv args = {
2424 .argc = argc,
2425 .use_bytes_argv = 1,
2426 .bytes_argv = argv,
2427 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002428 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002429}
2430
2431
Victor Stinner331a6a52019-05-27 16:39:22 +02002432PyStatus
2433PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002434{
2435 _PyArgv args = {
2436 .argc = argc,
2437 .use_bytes_argv = 0,
2438 .bytes_argv = NULL,
2439 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002440 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002441}
2442
2443
Victor Stinner36242fd2019-07-01 19:13:50 +02002444PyStatus
2445PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2446 Py_ssize_t length, wchar_t **items)
2447{
2448 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2449 if (_PyStatus_EXCEPTION(status)) {
2450 return status;
2451 }
2452
2453 PyWideStringList list2 = {.length = length, .items = items};
2454 if (_PyWideStringList_Copy(list, &list2) < 0) {
2455 return _PyStatus_NO_MEMORY();
2456 }
2457 return _PyStatus_OK();
2458}
2459
2460
Victor Stinner331a6a52019-05-27 16:39:22 +02002461/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002462
2463 * Command line arguments
2464 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002465 * Py_xxx global configuration variables
2466
2467 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002468PyStatus
2469PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002470{
Victor Stinner331a6a52019-05-27 16:39:22 +02002471 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002472 PyWideStringList orig_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002473
Victor Stinner331a6a52019-05-27 16:39:22 +02002474 status = _Py_PreInitializeFromConfig(config, NULL);
2475 if (_PyStatus_EXCEPTION(status)) {
2476 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002477 }
2478
Victor Stinner331a6a52019-05-27 16:39:22 +02002479 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002480
Victor Stinner331a6a52019-05-27 16:39:22 +02002481 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2482 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002483 }
2484
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002485 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002486 status = core_read_precmdline(config, &precmdline);
2487 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002488 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002489 }
2490
Victor Stinner870b0352019-05-17 03:15:12 +02002491 assert(config->isolated >= 0);
2492 if (config->isolated) {
2493 config->use_environment = 0;
2494 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002495 }
2496
Victor Stinner331a6a52019-05-27 16:39:22 +02002497 status = config_read_cmdline(config);
2498 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002499 goto done;
2500 }
2501
Victor Stinner120b7072019-08-23 18:03:08 +01002502 /* Handle early PySys_AddXOption() calls */
2503 status = _PySys_ReadPreinitXOptions(config);
2504 if (_PyStatus_EXCEPTION(status)) {
2505 goto done;
2506 }
2507
Victor Stinner331a6a52019-05-27 16:39:22 +02002508 status = config_read(config);
2509 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002510 goto done;
2511 }
2512
Victor Stinnercab5d072019-05-17 19:01:14 +02002513 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002514 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002515 goto done;
2516 }
2517
2518 /* Check config consistency */
2519 assert(config->isolated >= 0);
2520 assert(config->use_environment >= 0);
2521 assert(config->dev_mode >= 0);
Victor Stinner1def7752020-04-23 03:03:24 +02002522 assert(config->_use_peg_parser >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002523 assert(config->install_signal_handlers >= 0);
2524 assert(config->use_hash_seed >= 0);
2525 assert(config->faulthandler >= 0);
2526 assert(config->tracemalloc >= 0);
2527 assert(config->site_import >= 0);
2528 assert(config->bytes_warning >= 0);
2529 assert(config->inspect >= 0);
2530 assert(config->interactive >= 0);
2531 assert(config->optimization_level >= 0);
2532 assert(config->parser_debug >= 0);
2533 assert(config->write_bytecode >= 0);
2534 assert(config->verbose >= 0);
2535 assert(config->quiet >= 0);
2536 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002537 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002538 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002539 assert(config->buffered_stdio >= 0);
2540 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002541 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002542 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2543 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002544 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2545 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2546 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002547 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002548 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002549 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002550 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002551 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002552 assert(config->prefix != NULL);
2553 assert(config->base_prefix != NULL);
2554 assert(config->exec_prefix != NULL);
2555 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002556 }
2557 assert(config->filesystem_encoding != NULL);
2558 assert(config->filesystem_errors != NULL);
2559 assert(config->stdio_encoding != NULL);
2560 assert(config->stdio_errors != NULL);
2561#ifdef MS_WINDOWS
2562 assert(config->legacy_windows_stdio >= 0);
2563#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002564 /* -c and -m options are exclusive */
2565 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002566 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002567 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002568 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002569
Victor Stinner331a6a52019-05-27 16:39:22 +02002570 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002571
2572done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002573 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002574 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002575 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002576}
Victor Stinner1075d162019-03-25 23:19:57 +01002577
2578
2579PyObject*
2580_Py_GetConfigsAsDict(void)
2581{
Victor Stinner331a6a52019-05-27 16:39:22 +02002582 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002583 PyObject *dict = NULL;
2584
Victor Stinner331a6a52019-05-27 16:39:22 +02002585 result = PyDict_New();
2586 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002587 goto error;
2588 }
2589
Victor Stinner331a6a52019-05-27 16:39:22 +02002590 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002591 dict = _Py_GetGlobalVariablesAsDict();
2592 if (dict == NULL) {
2593 goto error;
2594 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002595 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002596 goto error;
2597 }
2598 Py_CLEAR(dict);
2599
2600 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002601 PyThreadState *tstate = _PyThreadState_GET();
2602 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002603 dict = _PyPreConfig_AsDict(pre_config);
2604 if (dict == NULL) {
2605 goto error;
2606 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002607 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002608 goto error;
2609 }
2610 Py_CLEAR(dict);
2611
2612 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002613 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinner331a6a52019-05-27 16:39:22 +02002614 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002615 if (dict == NULL) {
2616 goto error;
2617 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002618 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002619 goto error;
2620 }
2621 Py_CLEAR(dict);
2622
Victor Stinner331a6a52019-05-27 16:39:22 +02002623 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002624
2625error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002626 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002627 Py_XDECREF(dict);
2628 return NULL;
2629}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002630
2631
2632static void
2633init_dump_ascii_wstr(const wchar_t *str)
2634{
2635 if (str == NULL) {
2636 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002637 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002638 }
2639
2640 PySys_WriteStderr("'");
2641 for (; *str != L'\0'; str++) {
2642 wchar_t ch = *str;
2643 if (ch == L'\'') {
2644 PySys_WriteStderr("\\'");
2645 } else if (0x20 <= ch && ch < 0x7f) {
2646 PySys_WriteStderr("%lc", ch);
2647 }
2648 else if (ch <= 0xff) {
2649 PySys_WriteStderr("\\x%02x", ch);
2650 }
2651#if SIZEOF_WCHAR_T > 2
2652 else if (ch > 0xffff) {
2653 PySys_WriteStderr("\\U%08x", ch);
2654 }
2655#endif
2656 else {
2657 PySys_WriteStderr("\\u%04x", ch);
2658 }
2659 }
2660 PySys_WriteStderr("'");
2661}
2662
2663
2664/* Dump the Python path configuration into sys.stderr */
2665void
2666_Py_DumpPathConfig(PyThreadState *tstate)
2667{
2668 PyObject *exc_type, *exc_value, *exc_tb;
2669 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2670
2671 PySys_WriteStderr("Python path configuration:\n");
2672
2673#define DUMP_CONFIG(NAME, FIELD) \
2674 do { \
2675 PySys_WriteStderr(" " NAME " = "); \
2676 init_dump_ascii_wstr(config->FIELD); \
2677 PySys_WriteStderr("\n"); \
2678 } while (0)
2679
Victor Stinnerda7933e2020-04-13 03:04:28 +02002680 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002681 DUMP_CONFIG("PYTHONHOME", home);
2682 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2683 DUMP_CONFIG("program name", program_name);
2684 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2685 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2686 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2687 PySys_WriteStderr(" import site = %i\n", config->site_import);
2688#undef DUMP_CONFIG
2689
2690#define DUMP_SYS(NAME) \
2691 do { \
2692 obj = PySys_GetObject(#NAME); \
2693 PySys_FormatStderr(" sys.%s = ", #NAME); \
2694 if (obj != NULL) { \
2695 PySys_FormatStderr("%A", obj); \
2696 } \
2697 else { \
2698 PySys_WriteStderr("(not set)"); \
2699 } \
2700 PySys_FormatStderr("\n"); \
2701 } while (0)
2702
2703 PyObject *obj;
2704 DUMP_SYS(_base_executable);
2705 DUMP_SYS(base_prefix);
2706 DUMP_SYS(base_exec_prefix);
2707 DUMP_SYS(executable);
2708 DUMP_SYS(prefix);
2709 DUMP_SYS(exec_prefix);
2710#undef DUMP_SYS
2711
2712 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2713 if (sys_path != NULL && PyList_Check(sys_path)) {
2714 PySys_WriteStderr(" sys.path = [\n");
2715 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2716 for (Py_ssize_t i=0; i < len; i++) {
2717 PyObject *path = PyList_GET_ITEM(sys_path, i);
2718 PySys_FormatStderr(" %A,\n", path);
2719 }
2720 PySys_WriteStderr(" ]\n");
2721 }
2722
2723 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2724}