blob: 201d930f7d8d20c96ad483b0c1efef59dcc3ddc7 [file] [log] [blame]
Victor Stinner6c785c02018-08-01 17:56:14 +02001#include "Python.h"
Victor Stinnere5014be2020-04-14 17:52:15 +02002#include "osdefs.h" // DELIM
Victor Stinner9fc57a32018-11-07 00:44:03 +01003#include "pycore_fileutils.h"
Victor Stinner95e2cbf2019-03-01 16:25:19 +01004#include "pycore_getopt.h"
Victor Stinnerfcdb0272019-09-23 14:45:47 +02005#include "pycore_initconfig.h"
Victor Stinnere5014be2020-04-14 17:52:15 +02006#include "pycore_interp.h" // _PyInterpreterState.runtime
Victor Stinnerfcdb0272019-09-23 14:45:47 +02007#include "pycore_pathconfig.h"
8#include "pycore_pyerrors.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01009#include "pycore_pylifecycle.h"
10#include "pycore_pymem.h"
Victor Stinnere5014be2020-04-14 17:52:15 +020011#include "pycore_pystate.h" // _PyThreadState_GET()
12#include <locale.h> // setlocale()
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020013#ifdef HAVE_LANGINFO_H
Victor Stinnere5014be2020-04-14 17:52:15 +020014# include <langinfo.h> // nl_langinfo(CODESET)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020015#endif
Victor Stinner95e2cbf2019-03-01 16:25:19 +010016#if defined(MS_WINDOWS) || defined(__CYGWIN__)
Victor Stinnere5014be2020-04-14 17:52:15 +020017# include <windows.h> // GetACP()
Victor Stinner95e2cbf2019-03-01 16:25:19 +010018# ifdef HAVE_IO_H
19# include <io.h>
20# endif
21# ifdef HAVE_FCNTL_H
Victor Stinnere5014be2020-04-14 17:52:15 +020022# include <fcntl.h> // O_BINARY
Victor Stinner95e2cbf2019-03-01 16:25:19 +010023# endif
Victor Stinnerb2457ef2018-08-29 13:25:36 +020024#endif
25
Victor Stinner6c785c02018-08-01 17:56:14 +020026
Victor Stinner95e2cbf2019-03-01 16:25:19 +010027/* --- Command line options --------------------------------------- */
28
Victor Stinner95e2cbf2019-03-01 16:25:19 +010029/* Short usage message (with %s for argv0) */
30static const char usage_line[] =
31"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
32
33/* Long usage message, split into parts < 512 bytes */
34static const char usage_1[] = "\
35Options and arguments (and corresponding environment variables):\n\
36-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
37 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
38-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
39-c cmd : program passed in as string (terminates option list)\n\
40-d : debug output from parser; also PYTHONDEBUG=x\n\
41-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
42-h : print this help message and exit (also --help)\n\
43";
44static const char usage_2[] = "\
45-i : inspect interactively after running script; forces a prompt even\n\
46 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
47-I : isolate Python from the user's environment (implies -E and -s)\n\
48-m mod : run library module as a script (terminates option list)\n\
49-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
50 .pyc extension; also PYTHONOPTIMIZE=x\n\
51-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
52 .pyc extension\n\
53-q : don't print version and copyright messages on interactive startup\n\
54-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
55-S : don't imply 'import site' on initialization\n\
56";
57static const char usage_3[] = "\
58-u : force the stdout and stderr streams to be unbuffered;\n\
59 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
60-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
61 can be supplied multiple times to increase verbosity\n\
62-V : print the Python version number and exit (also --version)\n\
63 when given twice, print more information about the build\n\
64-W arg : warning control; arg is action:message:category:module:lineno\n\
65 also PYTHONWARNINGS=arg\n\
66-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000067-X opt : set implementation-specific option. The following options are available:\n\
68\n\
69 -X faulthandler: enable faulthandler\n\
70 -X showrefcount: output the total reference count and number of used\n\
71 memory blocks when the program finishes or after each statement in the\n\
72 interactive interpreter. This only works on debug builds\n\
73 -X tracemalloc: start tracing Python memory allocations using the\n\
74 tracemalloc module. By default, only the most recent frame is stored in a\n\
75 traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\
76 traceback limit of NFRAME frames\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000077 -X importtime: show how long each import takes. It shows module name,\n\
78 cumulative time (including nested imports) and self time (excluding\n\
79 nested imports). Note that its output may be broken in multi-threaded\n\
80 application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
81 -X dev: enable CPythons development mode”, introducing additional runtime\n\
82 checks which are too expensive to be enabled by default. Effect of the\n\
83 developer mode:\n\
84 * Add default warning filter, as -W default\n\
85 * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\
86 * Enable the faulthandler module to dump the Python traceback on a crash\n\
87 * Enable asyncio debug mode\n\
88 * Set the dev_mode attribute of sys.flags to True\n\
89 * io.IOBase destructor logs close() exceptions\n\
90 -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\
91 locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\
92 otherwise activate automatically)\n\
93 -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
94 given directory instead of to the code tree\n\
95\n\
Victor Stinner95e2cbf2019-03-01 16:25:19 +010096--check-hash-based-pycs always|default|never:\n\
97 control how Python invalidates hash-based .pyc files\n\
98";
99static const char usage_4[] = "\
100file : program read from script file\n\
101- : program read from stdin (default; interactive mode if a tty)\n\
102arg ...: arguments passed to program in sys.argv[1:]\n\n\
103Other environment variables:\n\
104PYTHONSTARTUP: file executed on interactive startup (no default)\n\
105PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
106 default module search path. The result is sys.path.\n\
107";
108static const char usage_5[] =
109"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
110" The default module search path uses %s.\n"
111"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
Inada Naoki95826c72019-12-14 14:27:32 +0900112"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100113"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
114"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
115static const char usage_6[] =
116"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Serhiy Storchakae9c90aa2019-08-24 12:49:27 +0300117" to seed the hashes of str and bytes objects. It can also be set to an\n"
118" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100119" predictable seed.\n"
120"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
121" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
122" hooks.\n"
123"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
124" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
125" locale coercion and locale compatibility warnings on stderr.\n"
126"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
127" debugger. It can be set to the callable of your debugger of choice.\n"
128"PYTHONDEVMODE: enable the development mode.\n"
129"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
130
131#if defined(MS_WINDOWS)
132# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
133#else
134# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
135#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200136
137
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100138/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200139
Victor Stinner6c785c02018-08-01 17:56:14 +0200140/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200141 stdin and stdout error handler to "surrogateescape". */
142int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200143int Py_DebugFlag = 0; /* Needed by parser.c */
144int Py_VerboseFlag = 0; /* Needed by import.c */
145int Py_QuietFlag = 0; /* Needed by sysmodule.c */
146int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
147int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
148int Py_OptimizeFlag = 0; /* Needed by compile.c */
149int Py_NoSiteFlag = 0; /* Suppress 'import site' */
150int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
151int Py_FrozenFlag = 0; /* Needed by getpath.c */
152int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
153int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
154int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
155int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
156int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
157int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
158#ifdef MS_WINDOWS
159int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
160int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
161#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200162
163
Victor Stinner1075d162019-03-25 23:19:57 +0100164static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100165_Py_GetGlobalVariablesAsDict(void)
166{
167 PyObject *dict, *obj;
168
169 dict = PyDict_New();
170 if (dict == NULL) {
171 return NULL;
172 }
173
174#define SET_ITEM(KEY, EXPR) \
175 do { \
176 obj = (EXPR); \
177 if (obj == NULL) { \
178 return NULL; \
179 } \
180 int res = PyDict_SetItemString(dict, (KEY), obj); \
181 Py_DECREF(obj); \
182 if (res < 0) { \
183 goto fail; \
184 } \
185 } while (0)
186#define SET_ITEM_INT(VAR) \
187 SET_ITEM(#VAR, PyLong_FromLong(VAR))
188#define FROM_STRING(STR) \
189 ((STR != NULL) ? \
190 PyUnicode_FromString(STR) \
191 : (Py_INCREF(Py_None), Py_None))
192#define SET_ITEM_STR(VAR) \
193 SET_ITEM(#VAR, FROM_STRING(VAR))
194
195 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
196 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
197 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
198 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
199
200 SET_ITEM_INT(Py_UTF8Mode);
201 SET_ITEM_INT(Py_DebugFlag);
202 SET_ITEM_INT(Py_VerboseFlag);
203 SET_ITEM_INT(Py_QuietFlag);
204 SET_ITEM_INT(Py_InteractiveFlag);
205 SET_ITEM_INT(Py_InspectFlag);
206
207 SET_ITEM_INT(Py_OptimizeFlag);
208 SET_ITEM_INT(Py_NoSiteFlag);
209 SET_ITEM_INT(Py_BytesWarningFlag);
210 SET_ITEM_INT(Py_FrozenFlag);
211 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
212 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
213 SET_ITEM_INT(Py_NoUserSiteDirectory);
214 SET_ITEM_INT(Py_UnbufferedStdioFlag);
215 SET_ITEM_INT(Py_HashRandomizationFlag);
216 SET_ITEM_INT(Py_IsolatedFlag);
217
218#ifdef MS_WINDOWS
219 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
220 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
221#endif
222
223 return dict;
224
225fail:
226 Py_DECREF(dict);
227 return NULL;
228
229#undef FROM_STRING
230#undef SET_ITEM
231#undef SET_ITEM_INT
232#undef SET_ITEM_STR
233}
234
235
Victor Stinner331a6a52019-05-27 16:39:22 +0200236/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200237
Victor Stinner331a6a52019-05-27 16:39:22 +0200238PyStatus PyStatus_Ok(void)
239{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200240
Victor Stinner331a6a52019-05-27 16:39:22 +0200241PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200242{
Victor Stinner331a6a52019-05-27 16:39:22 +0200243 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner871ff772019-05-17 23:54:00 +0200244 .err_msg = err_msg};
245}
246
Victor Stinner331a6a52019-05-27 16:39:22 +0200247PyStatus PyStatus_NoMemory(void)
248{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200249
Victor Stinner331a6a52019-05-27 16:39:22 +0200250PyStatus PyStatus_Exit(int exitcode)
251{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200252
253
Victor Stinner331a6a52019-05-27 16:39:22 +0200254int PyStatus_IsError(PyStatus status)
255{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200256
Victor Stinner331a6a52019-05-27 16:39:22 +0200257int PyStatus_IsExit(PyStatus status)
258{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200259
Victor Stinner331a6a52019-05-27 16:39:22 +0200260int PyStatus_Exception(PyStatus status)
261{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200262
263
Victor Stinner331a6a52019-05-27 16:39:22 +0200264/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100265
266#ifndef NDEBUG
267int
Victor Stinner331a6a52019-05-27 16:39:22 +0200268_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100269{
270 assert(list->length >= 0);
271 if (list->length != 0) {
272 assert(list->items != NULL);
273 }
274 for (Py_ssize_t i = 0; i < list->length; i++) {
275 assert(list->items[i] != NULL);
276 }
277 return 1;
278}
279#endif /* Py_DEBUG */
280
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100281
Victor Stinner6c785c02018-08-01 17:56:14 +0200282void
Victor Stinner331a6a52019-05-27 16:39:22 +0200283_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200284{
Victor Stinner331a6a52019-05-27 16:39:22 +0200285 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100286 for (Py_ssize_t i=0; i < list->length; i++) {
287 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200288 }
Victor Stinner74f65682019-03-15 15:08:05 +0100289 PyMem_RawFree(list->items);
290 list->length = 0;
291 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200292}
293
294
Victor Stinner74f65682019-03-15 15:08:05 +0100295int
Victor Stinner331a6a52019-05-27 16:39:22 +0200296_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200297{
Victor Stinner331a6a52019-05-27 16:39:22 +0200298 assert(_PyWideStringList_CheckConsistency(list));
299 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100300
301 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200302 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100303 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300304 }
Victor Stinner74f65682019-03-15 15:08:05 +0100305
Victor Stinnerfb4ae152019-09-30 01:40:17 +0200306 PyWideStringList copy = _PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100307
308 size_t size = list2->length * sizeof(list2->items[0]);
309 copy.items = PyMem_RawMalloc(size);
310 if (copy.items == NULL) {
311 return -1;
312 }
313
314 for (Py_ssize_t i=0; i < list2->length; i++) {
315 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
316 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200317 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100318 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200319 }
Victor Stinner74f65682019-03-15 15:08:05 +0100320 copy.items[i] = item;
321 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200322 }
Victor Stinner74f65682019-03-15 15:08:05 +0100323
Victor Stinner331a6a52019-05-27 16:39:22 +0200324 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100325 *list = copy;
326 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200327}
328
329
Victor Stinner331a6a52019-05-27 16:39:22 +0200330PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100331PyWideStringList_Insert(PyWideStringList *list,
332 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100333{
Victor Stinner3842f292019-08-23 16:57:54 +0100334 Py_ssize_t len = list->length;
335 if (len == PY_SSIZE_T_MAX) {
Min ho Kim96e12d52019-07-22 06:12:33 +1000336 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200337 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100338 }
Victor Stinner3842f292019-08-23 16:57:54 +0100339 if (index < 0) {
340 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
341 }
342 if (index > len) {
343 index = len;
344 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100345
Victor Stinner74f65682019-03-15 15:08:05 +0100346 wchar_t *item2 = _PyMem_RawWcsdup(item);
347 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200348 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100349 }
Victor Stinner74f65682019-03-15 15:08:05 +0100350
Victor Stinner3842f292019-08-23 16:57:54 +0100351 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100352 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
353 if (items2 == NULL) {
354 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200355 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100356 }
357
Victor Stinner3842f292019-08-23 16:57:54 +0100358 if (index < len) {
359 memmove(&items2[index + 1],
360 &items2[index],
361 (len - index) * sizeof(items2[0]));
362 }
363
364 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100365 list->items = items2;
366 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200367 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100368}
369
370
Victor Stinner331a6a52019-05-27 16:39:22 +0200371PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100372PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
373{
374 return PyWideStringList_Insert(list, list->length, item);
375}
376
377
378PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200379_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100380{
381 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200382 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
383 if (_PyStatus_EXCEPTION(status)) {
384 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100385 }
386 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200387 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100388}
389
390
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100391static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200392_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100393{
394 for (Py_ssize_t i = 0; i < list->length; i++) {
395 if (wcscmp(list->items[i], item) == 0) {
396 return 1;
397 }
398 }
399 return 0;
400}
401
402
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100403PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200404_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100405{
Victor Stinner331a6a52019-05-27 16:39:22 +0200406 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100407
Victor Stinner74f65682019-03-15 15:08:05 +0100408 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100409 if (pylist == NULL) {
410 return NULL;
411 }
412
Victor Stinner74f65682019-03-15 15:08:05 +0100413 for (Py_ssize_t i = 0; i < list->length; i++) {
414 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
415 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100416 Py_DECREF(pylist);
417 return NULL;
418 }
Victor Stinner74f65682019-03-15 15:08:05 +0100419 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100420 }
421 return pylist;
422}
423
424
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100425/* --- Py_SetStandardStreamEncoding() ----------------------------- */
426
Victor Stinner124b9eb2018-08-29 01:29:06 +0200427/* Helper to allow an embedding application to override the normal
428 * mechanism that attempts to figure out an appropriate IO encoding
429 */
430
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200431static char *_Py_StandardStreamEncoding = NULL;
432static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200433
434int
435Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
436{
437 if (Py_IsInitialized()) {
438 /* This is too late to have any effect */
439 return -1;
440 }
441
442 int res = 0;
443
444 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
445 but Py_Initialize() can change the allocator. Use a known allocator
446 to be able to release the memory later. */
447 PyMemAllocatorEx old_alloc;
448 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
449
450 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
451 * initialised yet.
452 *
453 * However, the raw memory allocators are initialised appropriately
454 * as C static variables, so _PyMem_RawStrdup is OK even though
455 * Py_Initialize hasn't been called yet.
456 */
457 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200458 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200459 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
460 if (!_Py_StandardStreamEncoding) {
461 res = -2;
462 goto done;
463 }
464 }
465 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200466 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200467 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
468 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200469 PyMem_RawFree(_Py_StandardStreamEncoding);
470 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200471 res = -3;
472 goto done;
473 }
474 }
475#ifdef MS_WINDOWS
476 if (_Py_StandardStreamEncoding) {
477 /* Overriding the stream encoding implies legacy streams */
478 Py_LegacyWindowsStdioFlag = 1;
479 }
480#endif
481
482done:
483 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
484
485 return res;
486}
487
488
489void
490_Py_ClearStandardStreamEncoding(void)
491{
492 /* Use the same allocator than Py_SetStandardStreamEncoding() */
493 PyMemAllocatorEx old_alloc;
494 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
495
496 /* We won't need them anymore. */
497 if (_Py_StandardStreamEncoding) {
498 PyMem_RawFree(_Py_StandardStreamEncoding);
499 _Py_StandardStreamEncoding = NULL;
500 }
501 if (_Py_StandardStreamErrors) {
502 PyMem_RawFree(_Py_StandardStreamErrors);
503 _Py_StandardStreamErrors = NULL;
504 }
505
506 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
507}
508
509
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100510/* --- Py_GetArgcArgv() ------------------------------------------- */
511
512/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200513static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100514
515
516void
517_Py_ClearArgcArgv(void)
518{
519 PyMemAllocatorEx old_alloc;
520 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
521
Victor Stinner331a6a52019-05-27 16:39:22 +0200522 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100523
524 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
525}
526
527
Victor Stinner4fffd382019-03-06 01:44:31 +0100528static int
Victor Stinner74f65682019-03-15 15:08:05 +0100529_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100530{
Victor Stinner331a6a52019-05-27 16:39:22 +0200531 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100532 int res;
533
534 PyMemAllocatorEx old_alloc;
535 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
536
Victor Stinner331a6a52019-05-27 16:39:22 +0200537 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100538
539 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
540 return res;
541}
542
543
544/* Make the *original* argc/argv available to other modules.
545 This is rare, but it is needed by the secureware extension. */
546void
547Py_GetArgcArgv(int *argc, wchar_t ***argv)
548{
Victor Stinner74f65682019-03-15 15:08:05 +0100549 *argc = (int)orig_argv.length;
550 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100551}
552
553
Victor Stinner331a6a52019-05-27 16:39:22 +0200554/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100555
556#define DECODE_LOCALE_ERR(NAME, LEN) \
557 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200558 ? _PyStatus_ERR("cannot decode " NAME) \
559 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100560
Victor Stinner441b10c2019-09-28 04:28:35 +0200561
Victor Stinner6c785c02018-08-01 17:56:14 +0200562/* Free memory allocated in config, but don't clear all attributes */
563void
Victor Stinner331a6a52019-05-27 16:39:22 +0200564PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200565{
566#define CLEAR(ATTR) \
567 do { \
568 PyMem_RawFree(ATTR); \
569 ATTR = NULL; \
570 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200571
572 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200573 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200574 CLEAR(config->home);
575 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200576
Victor Stinner331a6a52019-05-27 16:39:22 +0200577 _PyWideStringList_Clear(&config->argv);
578 _PyWideStringList_Clear(&config->warnoptions);
579 _PyWideStringList_Clear(&config->xoptions);
580 _PyWideStringList_Clear(&config->module_search_paths);
581 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200582
583 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700584 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200585 CLEAR(config->prefix);
586 CLEAR(config->base_prefix);
587 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200588 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200589
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200590 CLEAR(config->filesystem_encoding);
591 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200592 CLEAR(config->stdio_encoding);
593 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100594 CLEAR(config->run_command);
595 CLEAR(config->run_module);
596 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400597 CLEAR(config->check_hash_pycs_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200598#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200599}
600
601
Victor Stinner8462a492019-10-01 12:06:16 +0200602void
Victor Stinner331a6a52019-05-27 16:39:22 +0200603_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200604{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200605 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200606
Victor Stinner022be022019-05-22 23:58:50 +0200607 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200608 config->isolated = -1;
609 config->use_environment = -1;
610 config->dev_mode = -1;
611 config->install_signal_handlers = 1;
612 config->use_hash_seed = -1;
613 config->faulthandler = -1;
614 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200615 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200616 config->parse_argv = 0;
617 config->site_import = -1;
618 config->bytes_warning = -1;
619 config->inspect = -1;
620 config->interactive = -1;
621 config->optimization_level = -1;
622 config->parser_debug= -1;
623 config->write_bytecode = -1;
624 config->verbose = -1;
625 config->quiet = -1;
626 config->user_site_directory = -1;
627 config->configure_c_stdio = 0;
628 config->buffered_stdio = -1;
629 config->_install_importlib = 1;
630 config->check_hash_pycs_mode = NULL;
631 config->pathconfig_warnings = -1;
632 config->_init_main = 1;
633#ifdef MS_WINDOWS
634 config->legacy_windows_stdio = -1;
635#endif
636}
637
638
Victor Stinner8462a492019-10-01 12:06:16 +0200639static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200640config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200641{
Victor Stinner8462a492019-10-01 12:06:16 +0200642 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200643
644 config->isolated = 0;
645 config->use_environment = 1;
646 config->site_import = 1;
647 config->bytes_warning = 0;
648 config->inspect = 0;
649 config->interactive = 0;
650 config->optimization_level = 0;
651 config->parser_debug= 0;
652 config->write_bytecode = 1;
653 config->verbose = 0;
654 config->quiet = 0;
655 config->user_site_directory = 1;
656 config->buffered_stdio = 1;
657 config->pathconfig_warnings = 1;
658#ifdef MS_WINDOWS
659 config->legacy_windows_stdio = 0;
660#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200661}
662
663
Victor Stinner8462a492019-10-01 12:06:16 +0200664void
Victor Stinner331a6a52019-05-27 16:39:22 +0200665PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200666{
Victor Stinner8462a492019-10-01 12:06:16 +0200667 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200668
Victor Stinner022be022019-05-22 23:58:50 +0200669 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200670 config->configure_c_stdio = 1;
671 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200672}
673
674
Victor Stinner8462a492019-10-01 12:06:16 +0200675void
Victor Stinner331a6a52019-05-27 16:39:22 +0200676PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200677{
Victor Stinner8462a492019-10-01 12:06:16 +0200678 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200679
Victor Stinner022be022019-05-22 23:58:50 +0200680 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200681 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200682 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200683 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200684 config->dev_mode = 0;
685 config->install_signal_handlers = 0;
686 config->use_hash_seed = 0;
687 config->faulthandler = 0;
688 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200689 config->pathconfig_warnings = 0;
690#ifdef MS_WINDOWS
691 config->legacy_windows_stdio = 0;
692#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200693}
694
695
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200696/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200697PyStatus
698PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200699{
Victor Stinner331a6a52019-05-27 16:39:22 +0200700 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
701 if (_PyStatus_EXCEPTION(status)) {
702 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200703 }
704
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200705 wchar_t *str2;
706 if (str != NULL) {
707 str2 = _PyMem_RawWcsdup(str);
708 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200709 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200710 }
711 }
712 else {
713 str2 = NULL;
714 }
715 PyMem_RawFree(*config_str);
716 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200717 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200718}
719
720
Victor Stinner331a6a52019-05-27 16:39:22 +0200721static PyStatus
722config_set_bytes_string(PyConfig *config, wchar_t **config_str,
723 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200724{
Victor Stinner331a6a52019-05-27 16:39:22 +0200725 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
726 if (_PyStatus_EXCEPTION(status)) {
727 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400728 }
729
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200730 wchar_t *str2;
731 if (str != NULL) {
732 size_t len;
733 str2 = Py_DecodeLocale(str, &len);
734 if (str2 == NULL) {
735 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200736 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200737 }
738 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200739 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200740 }
741 }
742 }
743 else {
744 str2 = NULL;
745 }
746 PyMem_RawFree(*config_str);
747 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200748 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200749}
750
751
Victor Stinner331a6a52019-05-27 16:39:22 +0200752#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
753 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400754
755
Victor Stinner70005ac2019-05-02 15:25:34 -0400756/* Decode str using Py_DecodeLocale() and set the result into *config_str.
757 Pre-initialize Python if needed to ensure that encodings are properly
758 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200759PyStatus
760PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200761 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400762{
Victor Stinner331a6a52019-05-27 16:39:22 +0200763 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400764}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200765
766
Victor Stinner331a6a52019-05-27 16:39:22 +0200767PyStatus
768_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200769{
Victor Stinner331a6a52019-05-27 16:39:22 +0200770 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200771
Victor Stinner331a6a52019-05-27 16:39:22 +0200772 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200773
774#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200775#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200776 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200777 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
778 if (_PyStatus_EXCEPTION(status)) { \
779 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200780 } \
781 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100782#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200783 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200784 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200785 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200786 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200787 } while (0)
788
Victor Stinner6d1c4672019-05-20 11:02:00 +0200789 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100790 COPY_ATTR(isolated);
791 COPY_ATTR(use_environment);
792 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200793 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200794 COPY_ATTR(use_hash_seed);
795 COPY_ATTR(hash_seed);
796 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200797 COPY_ATTR(faulthandler);
798 COPY_ATTR(tracemalloc);
799 COPY_ATTR(import_time);
800 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200801 COPY_ATTR(dump_refs);
802 COPY_ATTR(malloc_stats);
803
Victor Stinner124b9eb2018-08-29 01:29:06 +0200804 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200805 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200806 COPY_WSTR_ATTR(home);
807 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200808
Victor Stinnerae239f62019-05-16 17:02:56 +0200809 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100810 COPY_WSTRLIST(argv);
811 COPY_WSTRLIST(warnoptions);
812 COPY_WSTRLIST(xoptions);
813 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200814 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200815
Victor Stinner124b9eb2018-08-29 01:29:06 +0200816 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700817 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200818 COPY_WSTR_ATTR(prefix);
819 COPY_WSTR_ATTR(base_prefix);
820 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200821 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200822
Victor Stinner6c785c02018-08-01 17:56:14 +0200823 COPY_ATTR(site_import);
824 COPY_ATTR(bytes_warning);
825 COPY_ATTR(inspect);
826 COPY_ATTR(interactive);
827 COPY_ATTR(optimization_level);
828 COPY_ATTR(parser_debug);
829 COPY_ATTR(write_bytecode);
830 COPY_ATTR(verbose);
831 COPY_ATTR(quiet);
832 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200833 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200834 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400835 COPY_WSTR_ATTR(filesystem_encoding);
836 COPY_WSTR_ATTR(filesystem_errors);
837 COPY_WSTR_ATTR(stdio_encoding);
838 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200839#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200840 COPY_ATTR(legacy_windows_stdio);
841#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100842 COPY_ATTR(skip_source_first_line);
843 COPY_WSTR_ATTR(run_command);
844 COPY_WSTR_ATTR(run_module);
845 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400846 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200847 COPY_ATTR(pathconfig_warnings);
848 COPY_ATTR(_init_main);
Victor Stinner6c785c02018-08-01 17:56:14 +0200849
850#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200851#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200852#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200853 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200854}
855
856
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100857static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200858config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100859{
860 PyObject *dict;
861
862 dict = PyDict_New();
863 if (dict == NULL) {
864 return NULL;
865 }
866
867#define SET_ITEM(KEY, EXPR) \
868 do { \
869 PyObject *obj = (EXPR); \
870 if (obj == NULL) { \
871 goto fail; \
872 } \
873 int res = PyDict_SetItemString(dict, (KEY), obj); \
874 Py_DECREF(obj); \
875 if (res < 0) { \
876 goto fail; \
877 } \
878 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100879#define SET_ITEM_INT(ATTR) \
880 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
881#define SET_ITEM_UINT(ATTR) \
882 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100883#define FROM_WSTRING(STR) \
884 ((STR != NULL) ? \
885 PyUnicode_FromWideChar(STR, -1) \
886 : (Py_INCREF(Py_None), Py_None))
887#define SET_ITEM_WSTR(ATTR) \
888 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
889#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200890 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100891
Victor Stinner6d1c4672019-05-20 11:02:00 +0200892 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100893 SET_ITEM_INT(isolated);
894 SET_ITEM_INT(use_environment);
895 SET_ITEM_INT(dev_mode);
896 SET_ITEM_INT(install_signal_handlers);
897 SET_ITEM_INT(use_hash_seed);
898 SET_ITEM_UINT(hash_seed);
899 SET_ITEM_INT(faulthandler);
900 SET_ITEM_INT(tracemalloc);
901 SET_ITEM_INT(import_time);
902 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100903 SET_ITEM_INT(dump_refs);
904 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400905 SET_ITEM_WSTR(filesystem_encoding);
906 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100907 SET_ITEM_WSTR(pycache_prefix);
908 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200909 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100910 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100911 SET_ITEM_WSTRLIST(xoptions);
912 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200913 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100914 SET_ITEM_WSTR(home);
915 SET_ITEM_WSTRLIST(module_search_paths);
916 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700917 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100918 SET_ITEM_WSTR(prefix);
919 SET_ITEM_WSTR(base_prefix);
920 SET_ITEM_WSTR(exec_prefix);
921 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100922 SET_ITEM_INT(site_import);
923 SET_ITEM_INT(bytes_warning);
924 SET_ITEM_INT(inspect);
925 SET_ITEM_INT(interactive);
926 SET_ITEM_INT(optimization_level);
927 SET_ITEM_INT(parser_debug);
928 SET_ITEM_INT(write_bytecode);
929 SET_ITEM_INT(verbose);
930 SET_ITEM_INT(quiet);
931 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200932 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100933 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400934 SET_ITEM_WSTR(stdio_encoding);
935 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100936#ifdef MS_WINDOWS
937 SET_ITEM_INT(legacy_windows_stdio);
938#endif
939 SET_ITEM_INT(skip_source_first_line);
940 SET_ITEM_WSTR(run_command);
941 SET_ITEM_WSTR(run_module);
942 SET_ITEM_WSTR(run_filename);
943 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400944 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200945 SET_ITEM_INT(pathconfig_warnings);
946 SET_ITEM_INT(_init_main);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100947
948 return dict;
949
950fail:
951 Py_DECREF(dict);
952 return NULL;
953
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100954#undef FROM_WSTRING
955#undef SET_ITEM
956#undef SET_ITEM_INT
957#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100958#undef SET_ITEM_WSTR
959#undef SET_ITEM_WSTRLIST
960}
961
962
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100963static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200964config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200965{
Victor Stinner20004952019-03-26 02:31:11 +0100966 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200967}
968
969
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100970/* Get a copy of the environment variable as wchar_t*.
971 Return 0 on success, but *dest can be NULL.
972 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200973static PyStatus
974config_get_env_dup(PyConfig *config,
975 wchar_t **dest,
976 wchar_t *wname, char *name,
977 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200978{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200979 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100980 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200981
Victor Stinner20004952019-03-26 02:31:11 +0100982 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200983 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200984 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200985 }
986
987#ifdef MS_WINDOWS
988 const wchar_t *var = _wgetenv(wname);
989 if (!var || var[0] == '\0') {
990 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200991 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200992 }
993
Victor Stinner331a6a52019-05-27 16:39:22 +0200994 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +0200995#else
996 const char *var = getenv(name);
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 config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001003#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001004}
1005
1006
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001007#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001008 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001009
1010
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001011static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001012config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001013{
Victor Stinner022be022019-05-22 23:58:50 +02001014 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1015 /* Python and Isolated configuration ignore global variables */
1016 return;
1017 }
1018
Victor Stinner6c785c02018-08-01 17:56:14 +02001019#define COPY_FLAG(ATTR, VALUE) \
1020 if (config->ATTR == -1) { \
1021 config->ATTR = VALUE; \
1022 }
1023#define COPY_NOT_FLAG(ATTR, VALUE) \
1024 if (config->ATTR == -1) { \
1025 config->ATTR = !(VALUE); \
1026 }
1027
Victor Stinner20004952019-03-26 02:31:11 +01001028 COPY_FLAG(isolated, Py_IsolatedFlag);
1029 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001030 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1031 COPY_FLAG(inspect, Py_InspectFlag);
1032 COPY_FLAG(interactive, Py_InteractiveFlag);
1033 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1034 COPY_FLAG(parser_debug, Py_DebugFlag);
1035 COPY_FLAG(verbose, Py_VerboseFlag);
1036 COPY_FLAG(quiet, Py_QuietFlag);
1037#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001038 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1039#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001040 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001041
Victor Stinner6c785c02018-08-01 17:56:14 +02001042 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1043 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1044 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1045 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1046
Victor Stinner6c785c02018-08-01 17:56:14 +02001047#undef COPY_FLAG
1048#undef COPY_NOT_FLAG
1049}
1050
1051
1052/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001053static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001054config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001055{
1056#define COPY_FLAG(ATTR, VAR) \
1057 if (config->ATTR != -1) { \
1058 VAR = config->ATTR; \
1059 }
1060#define COPY_NOT_FLAG(ATTR, VAR) \
1061 if (config->ATTR != -1) { \
1062 VAR = !config->ATTR; \
1063 }
1064
Victor Stinner20004952019-03-26 02:31:11 +01001065 COPY_FLAG(isolated, Py_IsolatedFlag);
1066 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001067 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1068 COPY_FLAG(inspect, Py_InspectFlag);
1069 COPY_FLAG(interactive, Py_InteractiveFlag);
1070 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1071 COPY_FLAG(parser_debug, Py_DebugFlag);
1072 COPY_FLAG(verbose, Py_VerboseFlag);
1073 COPY_FLAG(quiet, Py_QuietFlag);
1074#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001075 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1076#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001077 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001078
Victor Stinner6c785c02018-08-01 17:56:14 +02001079 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1080 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1081 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1082 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1083
Victor Stinner6c785c02018-08-01 17:56:14 +02001084 /* Random or non-zero hash seed */
1085 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1086 config->hash_seed != 0);
1087
1088#undef COPY_FLAG
1089#undef COPY_NOT_FLAG
1090}
1091
1092
1093/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1094 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001095static PyStatus
1096config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001097{
Victor Stinner331a6a52019-05-27 16:39:22 +02001098 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001099
Victor Stinner6c785c02018-08-01 17:56:14 +02001100 /* If Py_SetProgramName() was called, use its value */
1101 const wchar_t *program_name = _Py_path_config.program_name;
1102 if (program_name != NULL) {
1103 config->program_name = _PyMem_RawWcsdup(program_name);
1104 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001105 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001106 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001107 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001108 }
1109
1110#ifdef __APPLE__
1111 /* On MacOS X, when the Python interpreter is embedded in an
1112 application bundle, it gets executed by a bootstrapping script
1113 that does os.execve() with an argv[0] that's different from the
1114 actual Python executable. This is needed to keep the Finder happy,
1115 or rather, to work around Apple's overly strict requirements of
1116 the process name. However, we still need a usable sys.executable,
1117 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001118 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001119 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001120 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001121 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001122 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1123 "PYTHONEXECUTABLE environment variable");
1124 if (_PyStatus_EXCEPTION(status)) {
1125 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001126 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001127 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001128 }
1129#ifdef WITH_NEXT_FRAMEWORK
1130 else {
1131 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1132 if (pyvenv_launcher && *pyvenv_launcher) {
1133 /* Used by Mac/Tools/pythonw.c to forward
1134 * the argv0 of the stub executable
1135 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001136 status = CONFIG_SET_BYTES_STR(config,
1137 &config->program_name,
1138 pyvenv_launcher,
1139 "__PYVENV_LAUNCHER__ environment variable");
1140 if (_PyStatus_EXCEPTION(status)) {
1141 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001142 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001143
1144 /*
1145 * This environment variable is used to communicate between
1146 * the stub launcher and the real interpreter and isn't needed
1147 * beyond this point.
1148 *
1149 * Clean up to avoid problems when launching other programs
1150 * later on.
1151 */
1152 (void)unsetenv("__PYVENV_LAUNCHER__");
1153
Victor Stinner331a6a52019-05-27 16:39:22 +02001154 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001155 }
1156 }
1157#endif /* WITH_NEXT_FRAMEWORK */
1158#endif /* __APPLE__ */
1159
Victor Stinnerfed02e12019-05-17 11:12:09 +02001160 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001161 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001162 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1163 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1164 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001165 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001166 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001167 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001168 }
1169
Victor Stinnerfed02e12019-05-17 11:12:09 +02001170 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001171#ifdef MS_WINDOWS
1172 const wchar_t *default_program_name = L"python";
1173#else
1174 const wchar_t *default_program_name = L"python3";
1175#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001176 status = PyConfig_SetString(config, &config->program_name,
1177 default_program_name);
1178 if (_PyStatus_EXCEPTION(status)) {
1179 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001180 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001181 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001182}
1183
Victor Stinner331a6a52019-05-27 16:39:22 +02001184static PyStatus
1185config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001186{
1187 assert(config->executable == NULL);
1188
1189 /* If Py_SetProgramFullPath() was called, use its value */
1190 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1191 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001192 PyStatus status = PyConfig_SetString(config,
1193 &config->executable,
1194 program_full_path);
1195 if (_PyStatus_EXCEPTION(status)) {
1196 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001197 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001198 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001199 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001200 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001201}
Victor Stinner6c785c02018-08-01 17:56:14 +02001202
Victor Stinner4fffd382019-03-06 01:44:31 +01001203
Victor Stinner6c785c02018-08-01 17:56:14 +02001204static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001205config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001206{
Victor Stinner74f65682019-03-15 15:08:05 +01001207 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001208}
1209
1210
Victor Stinner331a6a52019-05-27 16:39:22 +02001211static PyStatus
1212config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001213{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001214 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001215
1216 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001217 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001218 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001219 PyStatus status = PyConfig_SetString(config, &config->home, home);
1220 if (_PyStatus_EXCEPTION(status)) {
1221 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001222 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001223 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001224 }
1225
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001226 return CONFIG_GET_ENV_DUP(config, &config->home,
1227 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001228}
1229
1230
Victor Stinner331a6a52019-05-27 16:39:22 +02001231static PyStatus
1232config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001233{
Victor Stinner331a6a52019-05-27 16:39:22 +02001234 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001235
1236 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1237 /* Convert a text seed to a numeric one */
1238 if (seed_text && strcmp(seed_text, "random") != 0) {
1239 const char *endptr = seed_text;
1240 unsigned long seed;
1241 errno = 0;
1242 seed = strtoul(seed_text, (char **)&endptr, 10);
1243 if (*endptr != '\0'
1244 || seed > 4294967295UL
1245 || (errno == ERANGE && seed == ULONG_MAX))
1246 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001247 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001248 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001249 }
1250 /* Use a specific hash */
1251 config->use_hash_seed = 1;
1252 config->hash_seed = seed;
1253 }
1254 else {
1255 /* Use a random hash */
1256 config->use_hash_seed = 0;
1257 config->hash_seed = 0;
1258 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001259 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001260}
1261
1262
Victor Stinner6c785c02018-08-01 17:56:14 +02001263static int
1264config_wstr_to_int(const wchar_t *wstr, int *result)
1265{
1266 const wchar_t *endptr = wstr;
1267 errno = 0;
1268 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1269 if (*endptr != '\0' || errno == ERANGE) {
1270 return -1;
1271 }
1272 if (value < INT_MIN || value > INT_MAX) {
1273 return -1;
1274 }
1275
1276 *result = (int)value;
1277 return 0;
1278}
1279
1280
Victor Stinner331a6a52019-05-27 16:39:22 +02001281static PyStatus
1282config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001283{
Victor Stinner331a6a52019-05-27 16:39:22 +02001284 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001285 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001286
Victor Stinner6c785c02018-08-01 17:56:14 +02001287 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001288 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1289 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1290 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1291 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001292
1293 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001294 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001295 if (dont_write_bytecode) {
1296 config->write_bytecode = 0;
1297 }
1298
1299 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001300 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001301 if (no_user_site_directory) {
1302 config->user_site_directory = 0;
1303 }
1304
1305 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001306 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001307 if (unbuffered_stdio) {
1308 config->buffered_stdio = 0;
1309 }
1310
1311#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001312 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001313 "PYTHONLEGACYWINDOWSSTDIO");
1314#endif
1315
Victor Stinner331a6a52019-05-27 16:39:22 +02001316 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001317 config->dump_refs = 1;
1318 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001319 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001320 config->malloc_stats = 1;
1321 }
1322
Victor Stinner331a6a52019-05-27 16:39:22 +02001323 if (config->pythonpath_env == NULL) {
1324 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1325 L"PYTHONPATH", "PYTHONPATH");
1326 if (_PyStatus_EXCEPTION(status)) {
1327 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001328 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001329 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001330
1331 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001332 status = config_init_hash_seed(config);
1333 if (_PyStatus_EXCEPTION(status)) {
1334 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001335 }
1336 }
1337
Victor Stinner331a6a52019-05-27 16:39:22 +02001338 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001339}
1340
1341
Victor Stinner331a6a52019-05-27 16:39:22 +02001342static PyStatus
1343config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001344{
1345 int nframe;
1346 int valid;
1347
Victor Stinner331a6a52019-05-27 16:39:22 +02001348 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001349 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001350 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001351 valid = (nframe >= 0);
1352 }
1353 else {
1354 valid = 0;
1355 }
1356 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001357 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001358 }
1359 config->tracemalloc = nframe;
1360 }
1361
1362 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1363 if (xoption) {
1364 const wchar_t *sep = wcschr(xoption, L'=');
1365 if (sep) {
1366 if (!config_wstr_to_int(sep + 1, &nframe)) {
1367 valid = (nframe >= 0);
1368 }
1369 else {
1370 valid = 0;
1371 }
1372 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001373 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1374 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001375 }
1376 }
1377 else {
1378 /* -X tracemalloc behaves as -X tracemalloc=1 */
1379 nframe = 1;
1380 }
1381 config->tracemalloc = nframe;
1382 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001383 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001384}
1385
1386
Victor Stinner331a6a52019-05-27 16:39:22 +02001387static PyStatus
1388config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001389{
1390 assert(config->pycache_prefix == NULL);
1391
1392 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1393 if (xoption) {
1394 const wchar_t *sep = wcschr(xoption, L'=');
1395 if (sep && wcslen(sep) > 1) {
1396 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1397 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001398 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001399 }
1400 }
1401 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001402 // PYTHONPYCACHEPREFIX env var ignored
1403 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001404 config->pycache_prefix = NULL;
1405 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001406 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001407 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001408
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001409 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1410 L"PYTHONPYCACHEPREFIX",
1411 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001412}
1413
1414
Victor Stinner331a6a52019-05-27 16:39:22 +02001415static PyStatus
1416config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001417{
1418 /* More complex options configured by env var and -X option */
1419 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001420 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001421 || config_get_xoption(config, L"faulthandler")) {
1422 config->faulthandler = 1;
1423 }
1424 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001425 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001426 || config_get_xoption(config, L"importtime")) {
1427 config->import_time = 1;
1428 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001429
Victor Stinner331a6a52019-05-27 16:39:22 +02001430 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001431 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001432 status = config_init_tracemalloc(config);
1433 if (_PyStatus_EXCEPTION(status)) {
1434 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001435 }
1436 }
1437
1438 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001439 status = config_init_pycache_prefix(config);
1440 if (_PyStatus_EXCEPTION(status)) {
1441 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001442 }
1443 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001444 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001445}
1446
1447
Victor Stinner709d23d2019-05-02 14:56:30 -04001448static const wchar_t *
Andy Lesteraa450a02020-03-07 11:36:04 -06001449config_get_stdio_errors(void)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001450{
1451#ifndef MS_WINDOWS
1452 const char *loc = setlocale(LC_CTYPE, NULL);
1453 if (loc != NULL) {
1454 /* surrogateescape is the default in the legacy C and POSIX locales */
1455 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001456 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001457 }
1458
1459#ifdef PY_COERCE_C_LOCALE
1460 /* surrogateescape is the default in locale coercion target locales */
1461 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001462 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001463 }
1464#endif
1465 }
1466
Victor Stinner709d23d2019-05-02 14:56:30 -04001467 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001468#else
1469 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001470 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001471#endif
1472}
1473
1474
Victor Stinner331a6a52019-05-27 16:39:22 +02001475static PyStatus
1476config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001477{
1478#ifdef MS_WINDOWS
1479 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001480 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001481 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001482#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001483 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001484#else
1485 const char *encoding = nl_langinfo(CODESET);
1486 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001487 return _PyStatus_ERR("failed to get the locale encoding: "
1488 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001489 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001490 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001491 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001492 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001493 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001494#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001495}
1496
1497
Victor Stinner331a6a52019-05-27 16:39:22 +02001498static PyStatus
1499config_init_stdio_encoding(PyConfig *config,
1500 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001501{
Victor Stinner331a6a52019-05-27 16:39:22 +02001502 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001503
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001504 /* If Py_SetStandardStreamEncoding() have been called, use these
1505 parameters. */
1506 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001507 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1508 _Py_StandardStreamEncoding,
1509 "_Py_StandardStreamEncoding");
1510 if (_PyStatus_EXCEPTION(status)) {
1511 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001512 }
1513 }
1514
1515 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001516 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1517 _Py_StandardStreamErrors,
1518 "_Py_StandardStreamErrors");
1519 if (_PyStatus_EXCEPTION(status)) {
1520 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001521 }
1522 }
1523
1524 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001525 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001526 }
1527
1528 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001529 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001530 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001531 char *pythonioencoding = _PyMem_RawStrdup(opt);
1532 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001533 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001534 }
1535
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001536 char *errors = strchr(pythonioencoding, ':');
1537 if (errors) {
1538 *errors = '\0';
1539 errors++;
1540 if (!errors[0]) {
1541 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001542 }
1543 }
1544
1545 /* Does PYTHONIOENCODING contain an encoding? */
1546 if (pythonioencoding[0]) {
1547 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001548 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1549 pythonioencoding,
1550 "PYTHONIOENCODING environment variable");
1551 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001552 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001553 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001554 }
1555 }
1556
1557 /* If the encoding is set but not the error handler,
1558 use "strict" error handler by default.
1559 PYTHONIOENCODING=latin1 behaves as
1560 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001561 if (!errors) {
1562 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001563 }
1564 }
1565
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001566 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001567 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1568 errors,
1569 "PYTHONIOENCODING environment variable");
1570 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001571 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001572 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001573 }
1574 }
1575
1576 PyMem_RawFree(pythonioencoding);
1577 }
1578
1579 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001580 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001581 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001582 status = PyConfig_SetString(config, &config->stdio_encoding,
1583 L"utf-8");
1584 if (_PyStatus_EXCEPTION(status)) {
1585 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001586 }
1587 }
1588 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001589 status = PyConfig_SetString(config, &config->stdio_errors,
1590 L"surrogateescape");
1591 if (_PyStatus_EXCEPTION(status)) {
1592 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001593 }
1594 }
1595 }
1596
1597 /* Choose the default error handler based on the current locale. */
1598 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001599 status = config_get_locale_encoding(config, &config->stdio_encoding);
1600 if (_PyStatus_EXCEPTION(status)) {
1601 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001602 }
1603 }
1604 if (config->stdio_errors == NULL) {
Andy Lesteraa450a02020-03-07 11:36:04 -06001605 const wchar_t *errors = config_get_stdio_errors();
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001606 assert(errors != NULL);
1607
Victor Stinner331a6a52019-05-27 16:39:22 +02001608 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1609 if (_PyStatus_EXCEPTION(status)) {
1610 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001611 }
1612 }
1613
Victor Stinner331a6a52019-05-27 16:39:22 +02001614 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001615}
1616
1617
Victor Stinner331a6a52019-05-27 16:39:22 +02001618static PyStatus
1619config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001620{
Victor Stinner331a6a52019-05-27 16:39:22 +02001621 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001622
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001623 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001624#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001625 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001626#else
Victor Stinnere2510952019-05-02 11:28:57 -04001627
1628#ifdef MS_WINDOWS
1629 if (preconfig->legacy_windows_fs_encoding) {
1630 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001631 status = PyConfig_SetString(config, &config->filesystem_encoding,
1632 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001633 }
1634 else
1635#endif
Victor Stinner20004952019-03-26 02:31:11 +01001636 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001637 status = PyConfig_SetString(config, &config->filesystem_encoding,
1638 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001639 }
Victor Stinnere2510952019-05-02 11:28:57 -04001640#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001641 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001642 status = PyConfig_SetString(config, &config->filesystem_encoding,
1643 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001644 }
Victor Stinnere2510952019-05-02 11:28:57 -04001645#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001646 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001647#ifdef MS_WINDOWS
1648 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001649 status = PyConfig_SetString(config, &config->filesystem_encoding,
1650 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001651#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001652 status = config_get_locale_encoding(config,
1653 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001654#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001655 }
Victor Stinnere2510952019-05-02 11:28:57 -04001656#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001657
Victor Stinner331a6a52019-05-27 16:39:22 +02001658 if (_PyStatus_EXCEPTION(status)) {
1659 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001660 }
1661 }
1662
1663 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001664 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001665#ifdef MS_WINDOWS
1666 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001667 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001668 }
1669 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001670 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001671 }
1672#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001673 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001674#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001675 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1676 if (_PyStatus_EXCEPTION(status)) {
1677 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001678 }
1679 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001680 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001681}
1682
1683
Victor Stinner331a6a52019-05-27 16:39:22 +02001684static PyStatus
1685config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001686{
Victor Stinner331a6a52019-05-27 16:39:22 +02001687 PyStatus status;
1688 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001689
Victor Stinner20004952019-03-26 02:31:11 +01001690 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001691 status = config_read_env_vars(config);
1692 if (_PyStatus_EXCEPTION(status)) {
1693 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001694 }
1695 }
1696
1697 /* -X options */
1698 if (config_get_xoption(config, L"showrefcount")) {
1699 config->show_ref_count = 1;
1700 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001701
Victor Stinner331a6a52019-05-27 16:39:22 +02001702 status = config_read_complex_options(config);
1703 if (_PyStatus_EXCEPTION(status)) {
1704 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001705 }
1706
Victor Stinner6c785c02018-08-01 17:56:14 +02001707 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001708 status = config_init_home(config);
1709 if (_PyStatus_EXCEPTION(status)) {
1710 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001711 }
1712 }
1713
Steve Dower177a41a2018-11-17 20:41:48 -08001714 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001715 status = config_init_executable(config);
1716 if (_PyStatus_EXCEPTION(status)) {
1717 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001718 }
1719 }
1720
Victor Stinner6c785c02018-08-01 17:56:14 +02001721 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001722 status = _PyConfig_InitPathConfig(config);
1723 if (_PyStatus_EXCEPTION(status)) {
1724 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001725 }
1726 }
1727
1728 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001729 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001730 if (config->faulthandler < 0) {
1731 config->faulthandler = 1;
1732 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001733 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001734 if (config->faulthandler < 0) {
1735 config->faulthandler = 0;
1736 }
1737 if (config->tracemalloc < 0) {
1738 config->tracemalloc = 0;
1739 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001740 if (config->use_hash_seed < 0) {
1741 config->use_hash_seed = 0;
1742 config->hash_seed = 0;
1743 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001744
Victor Stinner70fead22018-08-29 13:45:34 +02001745 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001746 status = config_init_fs_encoding(config, preconfig);
1747 if (_PyStatus_EXCEPTION(status)) {
1748 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001749 }
1750 }
1751
Victor Stinner331a6a52019-05-27 16:39:22 +02001752 status = config_init_stdio_encoding(config, preconfig);
1753 if (_PyStatus_EXCEPTION(status)) {
1754 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001755 }
1756
Victor Stinner62599762019-03-15 16:03:23 +01001757 if (config->argv.length < 1) {
1758 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001759 status = PyWideStringList_Append(&config->argv, L"");
1760 if (_PyStatus_EXCEPTION(status)) {
1761 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001762 }
1763 }
Victor Stinner870b0352019-05-17 03:15:12 +02001764
1765 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001766 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1767 L"default");
1768 if (_PyStatus_EXCEPTION(status)) {
1769 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001770 }
1771 }
1772
1773 if (config->configure_c_stdio < 0) {
1774 config->configure_c_stdio = 1;
1775 }
1776
Victor Stinner331a6a52019-05-27 16:39:22 +02001777 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001778}
Victor Stinner5ed69952018-11-06 15:59:52 +01001779
1780
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001781static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001782config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001783{
1784#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1785 /* don't translate newlines (\r\n <=> \n) */
1786 _setmode(fileno(stdin), O_BINARY);
1787 _setmode(fileno(stdout), O_BINARY);
1788 _setmode(fileno(stderr), O_BINARY);
1789#endif
1790
1791 if (!config->buffered_stdio) {
1792#ifdef HAVE_SETVBUF
1793 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1794 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1795 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1796#else /* !HAVE_SETVBUF */
1797 setbuf(stdin, (char *)NULL);
1798 setbuf(stdout, (char *)NULL);
1799 setbuf(stderr, (char *)NULL);
1800#endif /* !HAVE_SETVBUF */
1801 }
1802 else if (config->interactive) {
1803#ifdef MS_WINDOWS
1804 /* Doesn't have to have line-buffered -- use unbuffered */
1805 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1806 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1807#else /* !MS_WINDOWS */
1808#ifdef HAVE_SETVBUF
1809 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1810 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1811#endif /* HAVE_SETVBUF */
1812#endif /* !MS_WINDOWS */
1813 /* Leave stderr alone - it should be unbuffered anyway. */
1814 }
1815}
1816
1817
1818/* Write the configuration:
1819
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001820 - set Py_xxx global configuration variables
1821 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001822void
Victor Stinner331a6a52019-05-27 16:39:22 +02001823_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001824{
Victor Stinner331a6a52019-05-27 16:39:22 +02001825 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001826
1827 if (config->configure_c_stdio) {
1828 config_init_stdio(config);
1829 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001830
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001831 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001832 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001833 preconfig->isolated = config->isolated;
1834 preconfig->use_environment = config->use_environment;
1835 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001836}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001837
1838
Victor Stinner331a6a52019-05-27 16:39:22 +02001839/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001840
1841static void
Victor Stinner2f549082019-03-29 15:13:46 +01001842config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001843{
Victor Stinner2f549082019-03-29 15:13:46 +01001844 FILE *f = error ? stderr : stdout;
1845
1846 fprintf(f, usage_line, program);
1847 if (error)
1848 fprintf(f, "Try `python -h' for more information.\n");
1849 else {
1850 fputs(usage_1, f);
1851 fputs(usage_2, f);
1852 fputs(usage_3, f);
1853 fprintf(f, usage_4, (wint_t)DELIM);
1854 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1855 fputs(usage_6, f);
1856 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001857}
1858
1859
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001860/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001861static PyStatus
1862config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001863 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001864{
Victor Stinner331a6a52019-05-27 16:39:22 +02001865 PyStatus status;
1866 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001867 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001868 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001869
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001870 _PyOS_ResetGetOpt();
1871 do {
1872 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001873 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001874 if (c == EOF) {
1875 break;
1876 }
1877
1878 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001879 if (config->run_command == NULL) {
1880 /* -c is the last option; following arguments
1881 that look like options are left for the
1882 command to interpret. */
1883 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1884 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1885 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001886 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001887 }
1888 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1889 command[len - 2] = '\n';
1890 command[len - 1] = 0;
1891 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001892 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001893 break;
1894 }
1895
1896 if (c == 'm') {
1897 /* -m is the last option; following arguments
1898 that look like options are left for the
1899 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001900 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001901 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1902 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001903 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001904 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001905 }
1906 break;
1907 }
1908
1909 switch (c) {
1910 case 0:
1911 // Handle long option.
1912 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001913 if (wcscmp(_PyOS_optarg, L"always") == 0
1914 || wcscmp(_PyOS_optarg, L"never") == 0
1915 || wcscmp(_PyOS_optarg, L"default") == 0)
1916 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001917 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1918 _PyOS_optarg);
1919 if (_PyStatus_EXCEPTION(status)) {
1920 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001921 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001922 } else {
1923 fprintf(stderr, "--check-hash-based-pycs must be one of "
1924 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001925 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001926 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001927 }
1928 break;
1929
1930 case 'b':
1931 config->bytes_warning++;
1932 break;
1933
1934 case 'd':
1935 config->parser_debug++;
1936 break;
1937
1938 case 'i':
1939 config->inspect++;
1940 config->interactive++;
1941 break;
1942
Victor Stinner6dcb5422019-03-05 02:44:12 +01001943 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001944 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001945 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001946 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001947 break;
1948
1949 /* case 'J': reserved for Jython */
1950
1951 case 'O':
1952 config->optimization_level++;
1953 break;
1954
1955 case 'B':
1956 config->write_bytecode = 0;
1957 break;
1958
1959 case 's':
1960 config->user_site_directory = 0;
1961 break;
1962
1963 case 'S':
1964 config->site_import = 0;
1965 break;
1966
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001967 case 't':
1968 /* ignored for backwards compatibility */
1969 break;
1970
1971 case 'u':
1972 config->buffered_stdio = 0;
1973 break;
1974
1975 case 'v':
1976 config->verbose++;
1977 break;
1978
1979 case 'x':
1980 config->skip_source_first_line = 1;
1981 break;
1982
1983 case 'h':
1984 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001985 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001986 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001987
1988 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01001989 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001990 break;
1991
1992 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02001993 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
1994 if (_PyStatus_EXCEPTION(status)) {
1995 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001996 }
1997 break;
1998
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001999 case 'q':
2000 config->quiet++;
2001 break;
2002
2003 case 'R':
2004 config->use_hash_seed = 0;
2005 break;
2006
2007 /* This space reserved for other options */
2008
2009 default:
2010 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002011 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002012 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002013 }
2014 } while (1);
2015
Victor Stinner2f549082019-03-29 15:13:46 +01002016 if (print_version) {
2017 printf("Python %s\n",
2018 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002019 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002020 }
2021
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002022 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002023 && _PyOS_optind < argv->length
2024 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002025 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002026 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002027 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002028 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002029 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002030 }
2031 }
2032
2033 if (config->run_command != NULL || config->run_module != NULL) {
2034 /* Backup _PyOS_optind */
2035 _PyOS_optind--;
2036 }
2037
Victor Stinnerae239f62019-05-16 17:02:56 +02002038 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002039
Victor Stinner331a6a52019-05-27 16:39:22 +02002040 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002041}
2042
2043
2044#ifdef MS_WINDOWS
2045# define WCSTOK wcstok_s
2046#else
2047# define WCSTOK wcstok
2048#endif
2049
2050/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002051static PyStatus
2052config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002053{
Victor Stinner331a6a52019-05-27 16:39:22 +02002054 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002055 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2056 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002057 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002058 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002059 if (_PyStatus_EXCEPTION(status)) {
2060 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002061 }
2062
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002063 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002064 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002065 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002066 }
2067
2068
2069 wchar_t *warning, *context = NULL;
2070 for (warning = WCSTOK(env, L",", &context);
2071 warning != NULL;
2072 warning = WCSTOK(NULL, L",", &context))
2073 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002074 status = PyWideStringList_Append(warnoptions, warning);
2075 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002076 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002077 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002078 }
2079 }
2080 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002081 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002082}
2083
2084
Victor Stinner331a6a52019-05-27 16:39:22 +02002085static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002086warnoptions_append(PyConfig *config, PyWideStringList *options,
2087 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002088{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002089 /* config_init_warnoptions() add existing config warnoptions at the end:
2090 ensure that the new option is not already present in this list to
2091 prevent change the options order whne config_init_warnoptions() is
2092 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002093 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002094 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002095 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002096 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002097 if (_PyWideStringList_Find(options, option)) {
2098 /* Already present: do nothing */
2099 return _PyStatus_OK();
2100 }
2101 return PyWideStringList_Append(options, option);
2102}
2103
2104
2105static PyStatus
2106warnoptions_extend(PyConfig *config, PyWideStringList *options,
2107 const PyWideStringList *options2)
2108{
2109 const Py_ssize_t len = options2->length;
2110 wchar_t *const *items = options2->items;
2111
2112 for (Py_ssize_t i = 0; i < len; i++) {
2113 PyStatus status = warnoptions_append(config, options, items[i]);
2114 if (_PyStatus_EXCEPTION(status)) {
2115 return status;
2116 }
2117 }
2118 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002119}
2120
2121
Victor Stinner331a6a52019-05-27 16:39:22 +02002122static PyStatus
2123config_init_warnoptions(PyConfig *config,
2124 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002125 const PyWideStringList *env_warnoptions,
2126 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002127{
Victor Stinner331a6a52019-05-27 16:39:22 +02002128 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002129 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002130
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002131 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002132 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002133 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002134 * - PyConfig.dev_mode: "default" filter
2135 * - PYTHONWARNINGS environment variable
2136 * - '-W' command line options
2137 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2138 * "default::BytesWarning" or "error::BytesWarning" filter
2139 * - early PySys_AddWarnOption() calls
2140 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002141 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002142 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2143 * module works on the basis of "the most recently added filter will be
2144 * checked first", we add the lowest precedence entries first so that later
2145 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002146 */
2147
Victor Stinner20004952019-03-26 02:31:11 +01002148 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002149 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002150 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002151 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002152 }
2153 }
2154
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002155 status = warnoptions_extend(config, &options, env_warnoptions);
2156 if (_PyStatus_EXCEPTION(status)) {
2157 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002158 }
2159
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002160 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2161 if (_PyStatus_EXCEPTION(status)) {
2162 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002163 }
2164
2165 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2166 * don't even try to emit a warning, so we skip setting the filter in that
2167 * case.
2168 */
2169 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002170 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002171 if (config->bytes_warning> 1) {
2172 filter = L"error::BytesWarning";
2173 }
2174 else {
2175 filter = L"default::BytesWarning";
2176 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002177 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002178 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002179 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002180 }
2181 }
Victor Stinner120b7072019-08-23 18:03:08 +01002182
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002183 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002184 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002185 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002186 }
2187
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002188 /* Always add all PyConfig.warnoptions options */
2189 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2190 if (_PyStatus_EXCEPTION(status)) {
2191 goto error;
2192 }
2193
2194 _PyWideStringList_Clear(&config->warnoptions);
2195 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002196 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002197
2198error:
2199 _PyWideStringList_Clear(&options);
2200 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002201}
2202
2203
Victor Stinner331a6a52019-05-27 16:39:22 +02002204static PyStatus
2205config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002206{
Victor Stinner331a6a52019-05-27 16:39:22 +02002207 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002208 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002209
Victor Stinner74f65682019-03-15 15:08:05 +01002210 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002211 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002212 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002213 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2214 if (_PyStatus_EXCEPTION(status)) {
2215 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002216 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002217 }
2218 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002219 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002220 slice.length = cmdline_argv->length - opt_index;
2221 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002222 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2223 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002224 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002225 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002226 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002227
2228 wchar_t *arg0 = NULL;
2229 if (config->run_command != NULL) {
2230 /* Force sys.argv[0] = '-c' */
2231 arg0 = L"-c";
2232 }
2233 else if (config->run_module != NULL) {
2234 /* Force sys.argv[0] = '-m'*/
2235 arg0 = L"-m";
2236 }
Victor Stinner3939c322019-06-25 15:02:43 +02002237
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002238 if (arg0 != NULL) {
2239 arg0 = _PyMem_RawWcsdup(arg0);
2240 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002241 _PyWideStringList_Clear(&config_argv);
2242 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002243 }
2244
Victor Stinnerfa153762019-03-20 04:25:38 +01002245 PyMem_RawFree(config_argv.items[0]);
2246 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002247 }
2248
Victor Stinner331a6a52019-05-27 16:39:22 +02002249 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002250 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002251 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002252}
2253
2254
Victor Stinner331a6a52019-05-27 16:39:22 +02002255static PyStatus
2256core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002257{
Victor Stinner331a6a52019-05-27 16:39:22 +02002258 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002259
Victor Stinnercab5d072019-05-17 19:01:14 +02002260 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002261 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2262 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002263 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002264 }
2265
Victor Stinner331a6a52019-05-27 16:39:22 +02002266 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002267
2268 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2269 if (_PyStatus_EXCEPTION(status)) {
2270 return status;
2271 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002272
Victor Stinner331a6a52019-05-27 16:39:22 +02002273 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002274
Victor Stinner331a6a52019-05-27 16:39:22 +02002275 status = _PyPreCmdline_Read(precmdline, &preconfig);
2276 if (_PyStatus_EXCEPTION(status)) {
2277 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002278 }
2279
Victor Stinner331a6a52019-05-27 16:39:22 +02002280 status = _PyPreCmdline_SetConfig(precmdline, config);
2281 if (_PyStatus_EXCEPTION(status)) {
2282 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002283 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002284 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002285}
2286
2287
Victor Stinner3939c322019-06-25 15:02:43 +02002288/* Get run_filename absolute path */
2289static PyStatus
2290config_run_filename_abspath(PyConfig *config)
2291{
2292 if (!config->run_filename) {
2293 return _PyStatus_OK();
2294 }
2295
2296#ifndef MS_WINDOWS
2297 if (_Py_isabs(config->run_filename)) {
2298 /* path is already absolute */
2299 return _PyStatus_OK();
2300 }
2301#endif
2302
2303 wchar_t *abs_filename;
2304 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2305 /* failed to get the absolute path of the command line filename:
2306 ignore the error, keep the relative path */
2307 return _PyStatus_OK();
2308 }
2309 if (abs_filename == NULL) {
2310 return _PyStatus_NO_MEMORY();
2311 }
2312
2313 PyMem_RawFree(config->run_filename);
2314 config->run_filename = abs_filename;
2315 return _PyStatus_OK();
2316}
2317
2318
Victor Stinner331a6a52019-05-27 16:39:22 +02002319static PyStatus
2320config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002321{
Victor Stinner331a6a52019-05-27 16:39:22 +02002322 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002323 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2324 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2325 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002326
Victor Stinnerae239f62019-05-16 17:02:56 +02002327 if (config->parse_argv < 0) {
2328 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002329 }
Victor Stinner870b0352019-05-17 03:15:12 +02002330
Victor Stinnerfed02e12019-05-17 11:12:09 +02002331 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002332 status = config_init_program_name(config);
2333 if (_PyStatus_EXCEPTION(status)) {
2334 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002335 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002336 }
Victor Stinner2f549082019-03-29 15:13:46 +01002337
Victor Stinnerae239f62019-05-16 17:02:56 +02002338 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002339 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002340 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2341 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002342 goto done;
2343 }
2344
Victor Stinner3939c322019-06-25 15:02:43 +02002345 status = config_run_filename_abspath(config);
2346 if (_PyStatus_EXCEPTION(status)) {
2347 goto done;
2348 }
2349
Victor Stinner331a6a52019-05-27 16:39:22 +02002350 status = config_update_argv(config, opt_index);
2351 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002352 goto done;
2353 }
Victor Stinner2f549082019-03-29 15:13:46 +01002354 }
Victor Stinner3939c322019-06-25 15:02:43 +02002355 else {
2356 status = config_run_filename_abspath(config);
2357 if (_PyStatus_EXCEPTION(status)) {
2358 goto done;
2359 }
2360 }
Victor Stinner2f549082019-03-29 15:13:46 +01002361
Victor Stinner2f549082019-03-29 15:13:46 +01002362 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002363 status = config_init_env_warnoptions(config, &env_warnoptions);
2364 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002365 goto done;
2366 }
2367 }
2368
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002369 /* Handle early PySys_AddWarnOption() calls */
2370 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2371 if (_PyStatus_EXCEPTION(status)) {
2372 goto done;
2373 }
2374
Victor Stinner331a6a52019-05-27 16:39:22 +02002375 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002376 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002377 &env_warnoptions,
2378 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002379 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002380 goto done;
2381 }
2382
Victor Stinner331a6a52019-05-27 16:39:22 +02002383 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002384
2385done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002386 _PyWideStringList_Clear(&cmdline_warnoptions);
2387 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002388 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002389 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002390}
2391
2392
Victor Stinner331a6a52019-05-27 16:39:22 +02002393PyStatus
2394_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002395{
Victor Stinner331a6a52019-05-27 16:39:22 +02002396 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2397 if (_PyStatus_EXCEPTION(status)) {
2398 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002399 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002400
Victor Stinner5f38b842019-05-01 02:30:12 +02002401 return _PyArgv_AsWstrList(args, &config->argv);
2402}
2403
2404
Victor Stinner70005ac2019-05-02 15:25:34 -04002405/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2406 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002407PyStatus
2408PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002409{
2410 _PyArgv args = {
2411 .argc = argc,
2412 .use_bytes_argv = 1,
2413 .bytes_argv = argv,
2414 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002415 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002416}
2417
2418
Victor Stinner331a6a52019-05-27 16:39:22 +02002419PyStatus
2420PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002421{
2422 _PyArgv args = {
2423 .argc = argc,
2424 .use_bytes_argv = 0,
2425 .bytes_argv = NULL,
2426 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002427 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002428}
2429
2430
Victor Stinner36242fd2019-07-01 19:13:50 +02002431PyStatus
2432PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2433 Py_ssize_t length, wchar_t **items)
2434{
2435 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2436 if (_PyStatus_EXCEPTION(status)) {
2437 return status;
2438 }
2439
2440 PyWideStringList list2 = {.length = length, .items = items};
2441 if (_PyWideStringList_Copy(list, &list2) < 0) {
2442 return _PyStatus_NO_MEMORY();
2443 }
2444 return _PyStatus_OK();
2445}
2446
2447
Victor Stinner331a6a52019-05-27 16:39:22 +02002448/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002449
2450 * Command line arguments
2451 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002452 * Py_xxx global configuration variables
2453
2454 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002455PyStatus
2456PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002457{
Victor Stinner331a6a52019-05-27 16:39:22 +02002458 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002459 PyWideStringList orig_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002460
Victor Stinner331a6a52019-05-27 16:39:22 +02002461 status = _Py_PreInitializeFromConfig(config, NULL);
2462 if (_PyStatus_EXCEPTION(status)) {
2463 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002464 }
2465
Victor Stinner331a6a52019-05-27 16:39:22 +02002466 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002467
Victor Stinner331a6a52019-05-27 16:39:22 +02002468 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2469 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002470 }
2471
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002472 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002473 status = core_read_precmdline(config, &precmdline);
2474 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002475 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002476 }
2477
Victor Stinner870b0352019-05-17 03:15:12 +02002478 assert(config->isolated >= 0);
2479 if (config->isolated) {
2480 config->use_environment = 0;
2481 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002482 }
2483
Victor Stinner331a6a52019-05-27 16:39:22 +02002484 status = config_read_cmdline(config);
2485 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002486 goto done;
2487 }
2488
Victor Stinner120b7072019-08-23 18:03:08 +01002489 /* Handle early PySys_AddXOption() calls */
2490 status = _PySys_ReadPreinitXOptions(config);
2491 if (_PyStatus_EXCEPTION(status)) {
2492 goto done;
2493 }
2494
Victor Stinner331a6a52019-05-27 16:39:22 +02002495 status = config_read(config);
2496 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002497 goto done;
2498 }
2499
Victor Stinnercab5d072019-05-17 19:01:14 +02002500 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002501 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002502 goto done;
2503 }
2504
2505 /* Check config consistency */
2506 assert(config->isolated >= 0);
2507 assert(config->use_environment >= 0);
2508 assert(config->dev_mode >= 0);
2509 assert(config->install_signal_handlers >= 0);
2510 assert(config->use_hash_seed >= 0);
2511 assert(config->faulthandler >= 0);
2512 assert(config->tracemalloc >= 0);
2513 assert(config->site_import >= 0);
2514 assert(config->bytes_warning >= 0);
2515 assert(config->inspect >= 0);
2516 assert(config->interactive >= 0);
2517 assert(config->optimization_level >= 0);
2518 assert(config->parser_debug >= 0);
2519 assert(config->write_bytecode >= 0);
2520 assert(config->verbose >= 0);
2521 assert(config->quiet >= 0);
2522 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002523 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002524 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002525 assert(config->buffered_stdio >= 0);
2526 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002527 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002528 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2529 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002530 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2531 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2532 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002533 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002534 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002535 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002536 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002537 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002538 assert(config->prefix != NULL);
2539 assert(config->base_prefix != NULL);
2540 assert(config->exec_prefix != NULL);
2541 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002542 }
2543 assert(config->filesystem_encoding != NULL);
2544 assert(config->filesystem_errors != NULL);
2545 assert(config->stdio_encoding != NULL);
2546 assert(config->stdio_errors != NULL);
2547#ifdef MS_WINDOWS
2548 assert(config->legacy_windows_stdio >= 0);
2549#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002550 /* -c and -m options are exclusive */
2551 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002552 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002553 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002554 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002555
Victor Stinner331a6a52019-05-27 16:39:22 +02002556 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002557
2558done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002559 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002560 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002561 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002562}
Victor Stinner1075d162019-03-25 23:19:57 +01002563
2564
2565PyObject*
2566_Py_GetConfigsAsDict(void)
2567{
Victor Stinner331a6a52019-05-27 16:39:22 +02002568 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002569 PyObject *dict = NULL;
2570
Victor Stinner331a6a52019-05-27 16:39:22 +02002571 result = PyDict_New();
2572 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002573 goto error;
2574 }
2575
Victor Stinner331a6a52019-05-27 16:39:22 +02002576 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002577 dict = _Py_GetGlobalVariablesAsDict();
2578 if (dict == NULL) {
2579 goto error;
2580 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002581 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002582 goto error;
2583 }
2584 Py_CLEAR(dict);
2585
2586 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002587 PyThreadState *tstate = _PyThreadState_GET();
2588 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002589 dict = _PyPreConfig_AsDict(pre_config);
2590 if (dict == NULL) {
2591 goto error;
2592 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002593 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002594 goto error;
2595 }
2596 Py_CLEAR(dict);
2597
2598 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002599 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinner331a6a52019-05-27 16:39:22 +02002600 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002601 if (dict == NULL) {
2602 goto error;
2603 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002604 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002605 goto error;
2606 }
2607 Py_CLEAR(dict);
2608
Victor Stinner331a6a52019-05-27 16:39:22 +02002609 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002610
2611error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002612 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002613 Py_XDECREF(dict);
2614 return NULL;
2615}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002616
2617
2618static void
2619init_dump_ascii_wstr(const wchar_t *str)
2620{
2621 if (str == NULL) {
2622 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002623 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002624 }
2625
2626 PySys_WriteStderr("'");
2627 for (; *str != L'\0'; str++) {
2628 wchar_t ch = *str;
2629 if (ch == L'\'') {
2630 PySys_WriteStderr("\\'");
2631 } else if (0x20 <= ch && ch < 0x7f) {
2632 PySys_WriteStderr("%lc", ch);
2633 }
2634 else if (ch <= 0xff) {
2635 PySys_WriteStderr("\\x%02x", ch);
2636 }
2637#if SIZEOF_WCHAR_T > 2
2638 else if (ch > 0xffff) {
2639 PySys_WriteStderr("\\U%08x", ch);
2640 }
2641#endif
2642 else {
2643 PySys_WriteStderr("\\u%04x", ch);
2644 }
2645 }
2646 PySys_WriteStderr("'");
2647}
2648
2649
2650/* Dump the Python path configuration into sys.stderr */
2651void
2652_Py_DumpPathConfig(PyThreadState *tstate)
2653{
2654 PyObject *exc_type, *exc_value, *exc_tb;
2655 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2656
2657 PySys_WriteStderr("Python path configuration:\n");
2658
2659#define DUMP_CONFIG(NAME, FIELD) \
2660 do { \
2661 PySys_WriteStderr(" " NAME " = "); \
2662 init_dump_ascii_wstr(config->FIELD); \
2663 PySys_WriteStderr("\n"); \
2664 } while (0)
2665
Victor Stinnerda7933e2020-04-13 03:04:28 +02002666 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002667 DUMP_CONFIG("PYTHONHOME", home);
2668 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2669 DUMP_CONFIG("program name", program_name);
2670 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2671 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2672 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2673 PySys_WriteStderr(" import site = %i\n", config->site_import);
2674#undef DUMP_CONFIG
2675
2676#define DUMP_SYS(NAME) \
2677 do { \
2678 obj = PySys_GetObject(#NAME); \
2679 PySys_FormatStderr(" sys.%s = ", #NAME); \
2680 if (obj != NULL) { \
2681 PySys_FormatStderr("%A", obj); \
2682 } \
2683 else { \
2684 PySys_WriteStderr("(not set)"); \
2685 } \
2686 PySys_FormatStderr("\n"); \
2687 } while (0)
2688
2689 PyObject *obj;
2690 DUMP_SYS(_base_executable);
2691 DUMP_SYS(base_prefix);
2692 DUMP_SYS(base_exec_prefix);
2693 DUMP_SYS(executable);
2694 DUMP_SYS(prefix);
2695 DUMP_SYS(exec_prefix);
2696#undef DUMP_SYS
2697
2698 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2699 if (sys_path != NULL && PyList_Check(sys_path)) {
2700 PySys_WriteStderr(" sys.path = [\n");
2701 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2702 for (Py_ssize_t i=0; i < len; i++) {
2703 PyObject *path = PyList_GET_ITEM(sys_path, i);
2704 PySys_FormatStderr(" %A,\n", path);
2705 }
2706 PySys_WriteStderr(" ]\n");
2707 }
2708
2709 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2710}