blob: 3caed385ef6af5b9bf86ff8184151def31c7cedd [file] [log] [blame]
Victor Stinner6c785c02018-08-01 17:56:14 +02001#include "Python.h"
Victor Stinner4f98f462020-04-15 04:01:58 +02002#include "pycore_fileutils.h" // _Py_HasFileSystemDefaultEncodeErrors
3#include "pycore_getopt.h" // _PyOS_GetOpt()
4#include "pycore_initconfig.h" // _PyStatus_OK()
Victor Stinnere5014be2020-04-14 17:52:15 +02005#include "pycore_interp.h" // _PyInterpreterState.runtime
Victor Stinner4f98f462020-04-15 04:01:58 +02006#include "pycore_pathconfig.h" // _Py_path_config
7#include "pycore_pyerrors.h" // _PyErr_Fetch()
8#include "pycore_pylifecycle.h" // _Py_PreInitializeFromConfig()
Victor Stinnerd9ea5ca2020-04-15 02:57:50 +02009#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
Victor Stinnere5014be2020-04-14 17:52:15 +020010#include "pycore_pystate.h" // _PyThreadState_GET()
Victor Stinner4f98f462020-04-15 04:01:58 +020011
12#include "osdefs.h" // DELIM
Victor Stinnere5014be2020-04-14 17:52:15 +020013#include <locale.h> // setlocale()
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020014#ifdef HAVE_LANGINFO_H
Victor Stinnere5014be2020-04-14 17:52:15 +020015# include <langinfo.h> // nl_langinfo(CODESET)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020016#endif
Victor Stinner95e2cbf2019-03-01 16:25:19 +010017#if defined(MS_WINDOWS) || defined(__CYGWIN__)
Victor Stinnere5014be2020-04-14 17:52:15 +020018# include <windows.h> // GetACP()
Victor Stinner95e2cbf2019-03-01 16:25:19 +010019# ifdef HAVE_IO_H
20# include <io.h>
21# endif
22# ifdef HAVE_FCNTL_H
Victor Stinnere5014be2020-04-14 17:52:15 +020023# include <fcntl.h> // O_BINARY
Victor Stinner95e2cbf2019-03-01 16:25:19 +010024# endif
Victor Stinnerb2457ef2018-08-29 13:25:36 +020025#endif
26
Victor Stinner81750642020-06-08 19:36:13 +020027#ifndef PLATLIBDIR
28# error "PLATLIBDIR macro must be defined"
29#endif
30
Victor Stinner6c785c02018-08-01 17:56:14 +020031
Victor Stinner95e2cbf2019-03-01 16:25:19 +010032/* --- Command line options --------------------------------------- */
33
Victor Stinner95e2cbf2019-03-01 16:25:19 +010034/* Short usage message (with %s for argv0) */
35static const char usage_line[] =
36"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
37
38/* Long usage message, split into parts < 512 bytes */
39static const char usage_1[] = "\
40Options and arguments (and corresponding environment variables):\n\
41-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
42 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
43-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
44-c cmd : program passed in as string (terminates option list)\n\
Miss Islington (bot)9b34f342020-12-02 14:01:23 -080045-d : turn on parser debugging output (for experts only, only works on\n\
46 debug builds); also PYTHONDEBUG=x\n\
Victor Stinner95e2cbf2019-03-01 16:25:19 +010047-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
48-h : print this help message and exit (also --help)\n\
49";
50static const char usage_2[] = "\
51-i : inspect interactively after running script; forces a prompt even\n\
52 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
53-I : isolate Python from the user's environment (implies -E and -s)\n\
54-m mod : run library module as a script (terminates option list)\n\
55-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
56 .pyc extension; also PYTHONOPTIMIZE=x\n\
57-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
58 .pyc extension\n\
59-q : don't print version and copyright messages on interactive startup\n\
60-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
61-S : don't imply 'import site' on initialization\n\
62";
63static const char usage_3[] = "\
64-u : force the stdout and stderr streams to be unbuffered;\n\
65 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
66-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
67 can be supplied multiple times to increase verbosity\n\
68-V : print the Python version number and exit (also --version)\n\
69 when given twice, print more information about the build\n\
70-W arg : warning control; arg is action:message:category:module:lineno\n\
71 also PYTHONWARNINGS=arg\n\
72-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000073-X opt : set implementation-specific option. The following options are available:\n\
74\n\
75 -X faulthandler: enable faulthandler\n\
Pablo Galindoc5fc1562020-04-22 23:29:27 +010076 -X oldparser: enable the traditional LL(1) parser; also PYTHONOLDPARSER\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000077 -X showrefcount: output the total reference count and number of used\n\
78 memory blocks when the program finishes or after each statement in the\n\
79 interactive interpreter. This only works on debug builds\n\
80 -X tracemalloc: start tracing Python memory allocations using the\n\
81 tracemalloc module. By default, only the most recent frame is stored in a\n\
82 traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\
83 traceback limit of NFRAME frames\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000084 -X importtime: show how long each import takes. It shows module name,\n\
85 cumulative time (including nested imports) and self time (excluding\n\
86 nested imports). Note that its output may be broken in multi-threaded\n\
87 application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
Miss Islington (bot)11a82c72020-09-08 17:47:53 -070088 -X dev: enable CPython's \"development mode\", introducing additional runtime\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000089 checks which are too expensive to be enabled by default. Effect of the\n\
90 developer mode:\n\
91 * Add default warning filter, as -W default\n\
92 * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\
93 * Enable the faulthandler module to dump the Python traceback on a crash\n\
94 * Enable asyncio debug mode\n\
95 * Set the dev_mode attribute of sys.flags to True\n\
96 * io.IOBase destructor logs close() exceptions\n\
97 -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\
98 locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\
99 otherwise activate automatically)\n\
100 -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
101 given directory instead of to the code tree\n\
102\n\
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100103--check-hash-based-pycs always|default|never:\n\
104 control how Python invalidates hash-based .pyc files\n\
105";
106static const char usage_4[] = "\
107file : program read from script file\n\
108- : program read from stdin (default; interactive mode if a tty)\n\
109arg ...: arguments passed to program in sys.argv[1:]\n\n\
110Other environment variables:\n\
111PYTHONSTARTUP: file executed on interactive startup (no default)\n\
112PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
113 default module search path. The result is sys.path.\n\
114";
115static const char usage_5[] =
116"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
117" The default module search path uses %s.\n"
Victor Stinner81750642020-06-08 19:36:13 +0200118"PYTHONPLATLIBDIR : override sys.platlibdir.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100119"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
Inada Naoki95826c72019-12-14 14:27:32 +0900120"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100121"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
122"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
123static const char usage_6[] =
124"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Serhiy Storchakae9c90aa2019-08-24 12:49:27 +0300125" to seed the hashes of str and bytes objects. It can also be set to an\n"
126" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100127" predictable seed.\n"
128"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
129" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
130" hooks.\n"
131"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
132" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
133" locale coercion and locale compatibility warnings on stderr.\n"
134"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
135" debugger. It can be set to the callable of your debugger of choice.\n"
136"PYTHONDEVMODE: enable the development mode.\n"
137"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
138
139#if defined(MS_WINDOWS)
140# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
141#else
142# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
143#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200144
145
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100146/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200147
Victor Stinner6c785c02018-08-01 17:56:14 +0200148/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200149 stdin and stdout error handler to "surrogateescape". */
150int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200151int Py_DebugFlag = 0; /* Needed by parser.c */
152int Py_VerboseFlag = 0; /* Needed by import.c */
153int Py_QuietFlag = 0; /* Needed by sysmodule.c */
154int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
155int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
156int Py_OptimizeFlag = 0; /* Needed by compile.c */
157int Py_NoSiteFlag = 0; /* Suppress 'import site' */
158int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
159int Py_FrozenFlag = 0; /* Needed by getpath.c */
160int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
161int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
162int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
163int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
164int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
165int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
166#ifdef MS_WINDOWS
167int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
168int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
169#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200170
171
Victor Stinner1075d162019-03-25 23:19:57 +0100172static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100173_Py_GetGlobalVariablesAsDict(void)
174{
175 PyObject *dict, *obj;
176
177 dict = PyDict_New();
178 if (dict == NULL) {
179 return NULL;
180 }
181
182#define SET_ITEM(KEY, EXPR) \
183 do { \
184 obj = (EXPR); \
185 if (obj == NULL) { \
186 return NULL; \
187 } \
188 int res = PyDict_SetItemString(dict, (KEY), obj); \
189 Py_DECREF(obj); \
190 if (res < 0) { \
191 goto fail; \
192 } \
193 } while (0)
194#define SET_ITEM_INT(VAR) \
195 SET_ITEM(#VAR, PyLong_FromLong(VAR))
196#define FROM_STRING(STR) \
197 ((STR != NULL) ? \
198 PyUnicode_FromString(STR) \
199 : (Py_INCREF(Py_None), Py_None))
200#define SET_ITEM_STR(VAR) \
201 SET_ITEM(#VAR, FROM_STRING(VAR))
202
203 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
204 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
205 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
206 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
207
208 SET_ITEM_INT(Py_UTF8Mode);
209 SET_ITEM_INT(Py_DebugFlag);
210 SET_ITEM_INT(Py_VerboseFlag);
211 SET_ITEM_INT(Py_QuietFlag);
212 SET_ITEM_INT(Py_InteractiveFlag);
213 SET_ITEM_INT(Py_InspectFlag);
214
215 SET_ITEM_INT(Py_OptimizeFlag);
216 SET_ITEM_INT(Py_NoSiteFlag);
217 SET_ITEM_INT(Py_BytesWarningFlag);
218 SET_ITEM_INT(Py_FrozenFlag);
219 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
220 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
221 SET_ITEM_INT(Py_NoUserSiteDirectory);
222 SET_ITEM_INT(Py_UnbufferedStdioFlag);
223 SET_ITEM_INT(Py_HashRandomizationFlag);
224 SET_ITEM_INT(Py_IsolatedFlag);
225
226#ifdef MS_WINDOWS
227 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
228 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
229#endif
230
231 return dict;
232
233fail:
234 Py_DECREF(dict);
235 return NULL;
236
237#undef FROM_STRING
238#undef SET_ITEM
239#undef SET_ITEM_INT
240#undef SET_ITEM_STR
241}
242
243
Victor Stinner331a6a52019-05-27 16:39:22 +0200244/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200245
Victor Stinner331a6a52019-05-27 16:39:22 +0200246PyStatus PyStatus_Ok(void)
247{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200248
Victor Stinner331a6a52019-05-27 16:39:22 +0200249PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200250{
Victor Stinner331a6a52019-05-27 16:39:22 +0200251 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner871ff772019-05-17 23:54:00 +0200252 .err_msg = err_msg};
253}
254
Victor Stinner331a6a52019-05-27 16:39:22 +0200255PyStatus PyStatus_NoMemory(void)
256{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200257
Victor Stinner331a6a52019-05-27 16:39:22 +0200258PyStatus PyStatus_Exit(int exitcode)
259{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200260
261
Victor Stinner331a6a52019-05-27 16:39:22 +0200262int PyStatus_IsError(PyStatus status)
263{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200264
Victor Stinner331a6a52019-05-27 16:39:22 +0200265int PyStatus_IsExit(PyStatus status)
266{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200267
Victor Stinner331a6a52019-05-27 16:39:22 +0200268int PyStatus_Exception(PyStatus status)
269{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200270
271
Victor Stinner331a6a52019-05-27 16:39:22 +0200272/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100273
274#ifndef NDEBUG
275int
Victor Stinner331a6a52019-05-27 16:39:22 +0200276_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100277{
278 assert(list->length >= 0);
279 if (list->length != 0) {
280 assert(list->items != NULL);
281 }
282 for (Py_ssize_t i = 0; i < list->length; i++) {
283 assert(list->items[i] != NULL);
284 }
285 return 1;
286}
287#endif /* Py_DEBUG */
288
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100289
Victor Stinner6c785c02018-08-01 17:56:14 +0200290void
Victor Stinner331a6a52019-05-27 16:39:22 +0200291_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200292{
Victor Stinner331a6a52019-05-27 16:39:22 +0200293 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100294 for (Py_ssize_t i=0; i < list->length; i++) {
295 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200296 }
Victor Stinner74f65682019-03-15 15:08:05 +0100297 PyMem_RawFree(list->items);
298 list->length = 0;
299 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200300}
301
302
Victor Stinner74f65682019-03-15 15:08:05 +0100303int
Victor Stinner331a6a52019-05-27 16:39:22 +0200304_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200305{
Victor Stinner331a6a52019-05-27 16:39:22 +0200306 assert(_PyWideStringList_CheckConsistency(list));
307 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100308
309 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200310 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100311 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300312 }
Victor Stinner74f65682019-03-15 15:08:05 +0100313
Victor Stinnerfb4ae152019-09-30 01:40:17 +0200314 PyWideStringList copy = _PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100315
316 size_t size = list2->length * sizeof(list2->items[0]);
317 copy.items = PyMem_RawMalloc(size);
318 if (copy.items == NULL) {
319 return -1;
320 }
321
322 for (Py_ssize_t i=0; i < list2->length; i++) {
323 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
324 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200325 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100326 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200327 }
Victor Stinner74f65682019-03-15 15:08:05 +0100328 copy.items[i] = item;
329 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200330 }
Victor Stinner74f65682019-03-15 15:08:05 +0100331
Victor Stinner331a6a52019-05-27 16:39:22 +0200332 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100333 *list = copy;
334 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200335}
336
337
Victor Stinner331a6a52019-05-27 16:39:22 +0200338PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100339PyWideStringList_Insert(PyWideStringList *list,
340 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100341{
Victor Stinner3842f292019-08-23 16:57:54 +0100342 Py_ssize_t len = list->length;
343 if (len == PY_SSIZE_T_MAX) {
Min ho Kim96e12d52019-07-22 06:12:33 +1000344 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200345 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100346 }
Victor Stinner3842f292019-08-23 16:57:54 +0100347 if (index < 0) {
348 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
349 }
350 if (index > len) {
351 index = len;
352 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100353
Victor Stinner74f65682019-03-15 15:08:05 +0100354 wchar_t *item2 = _PyMem_RawWcsdup(item);
355 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200356 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100357 }
Victor Stinner74f65682019-03-15 15:08:05 +0100358
Victor Stinner3842f292019-08-23 16:57:54 +0100359 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100360 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
361 if (items2 == NULL) {
362 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200363 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100364 }
365
Victor Stinner3842f292019-08-23 16:57:54 +0100366 if (index < len) {
367 memmove(&items2[index + 1],
368 &items2[index],
369 (len - index) * sizeof(items2[0]));
370 }
371
372 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100373 list->items = items2;
374 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200375 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100376}
377
378
Victor Stinner331a6a52019-05-27 16:39:22 +0200379PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100380PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
381{
382 return PyWideStringList_Insert(list, list->length, item);
383}
384
385
386PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200387_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100388{
389 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200390 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
391 if (_PyStatus_EXCEPTION(status)) {
392 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100393 }
394 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200395 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100396}
397
398
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100399static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200400_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100401{
402 for (Py_ssize_t i = 0; i < list->length; i++) {
403 if (wcscmp(list->items[i], item) == 0) {
404 return 1;
405 }
406 }
407 return 0;
408}
409
410
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100411PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200412_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100413{
Victor Stinner331a6a52019-05-27 16:39:22 +0200414 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100415
Victor Stinner74f65682019-03-15 15:08:05 +0100416 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100417 if (pylist == NULL) {
418 return NULL;
419 }
420
Victor Stinner74f65682019-03-15 15:08:05 +0100421 for (Py_ssize_t i = 0; i < list->length; i++) {
422 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
423 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100424 Py_DECREF(pylist);
425 return NULL;
426 }
Victor Stinner74f65682019-03-15 15:08:05 +0100427 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100428 }
429 return pylist;
430}
431
432
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100433/* --- Py_SetStandardStreamEncoding() ----------------------------- */
434
Victor Stinner124b9eb2018-08-29 01:29:06 +0200435/* Helper to allow an embedding application to override the normal
436 * mechanism that attempts to figure out an appropriate IO encoding
437 */
438
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200439static char *_Py_StandardStreamEncoding = NULL;
440static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200441
442int
443Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
444{
445 if (Py_IsInitialized()) {
446 /* This is too late to have any effect */
447 return -1;
448 }
449
450 int res = 0;
451
452 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
453 but Py_Initialize() can change the allocator. Use a known allocator
454 to be able to release the memory later. */
455 PyMemAllocatorEx old_alloc;
456 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
457
458 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
459 * initialised yet.
460 *
461 * However, the raw memory allocators are initialised appropriately
462 * as C static variables, so _PyMem_RawStrdup is OK even though
463 * Py_Initialize hasn't been called yet.
464 */
465 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200466 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200467 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
468 if (!_Py_StandardStreamEncoding) {
469 res = -2;
470 goto done;
471 }
472 }
473 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200474 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200475 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
476 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200477 PyMem_RawFree(_Py_StandardStreamEncoding);
478 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200479 res = -3;
480 goto done;
481 }
482 }
483#ifdef MS_WINDOWS
484 if (_Py_StandardStreamEncoding) {
485 /* Overriding the stream encoding implies legacy streams */
486 Py_LegacyWindowsStdioFlag = 1;
487 }
488#endif
489
490done:
491 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
492
493 return res;
494}
495
496
497void
498_Py_ClearStandardStreamEncoding(void)
499{
500 /* Use the same allocator than Py_SetStandardStreamEncoding() */
501 PyMemAllocatorEx old_alloc;
502 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
503
504 /* We won't need them anymore. */
505 if (_Py_StandardStreamEncoding) {
506 PyMem_RawFree(_Py_StandardStreamEncoding);
507 _Py_StandardStreamEncoding = NULL;
508 }
509 if (_Py_StandardStreamErrors) {
510 PyMem_RawFree(_Py_StandardStreamErrors);
511 _Py_StandardStreamErrors = NULL;
512 }
513
514 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
515}
516
517
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100518/* --- Py_GetArgcArgv() ------------------------------------------- */
519
520/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200521static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100522
523
524void
525_Py_ClearArgcArgv(void)
526{
527 PyMemAllocatorEx old_alloc;
528 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
529
Victor Stinner331a6a52019-05-27 16:39:22 +0200530 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100531
532 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
533}
534
535
Victor Stinner4fffd382019-03-06 01:44:31 +0100536static int
Victor Stinner74f65682019-03-15 15:08:05 +0100537_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100538{
Victor Stinner331a6a52019-05-27 16:39:22 +0200539 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100540 int res;
541
542 PyMemAllocatorEx old_alloc;
543 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
544
Victor Stinner331a6a52019-05-27 16:39:22 +0200545 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100546
547 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
548 return res;
549}
550
551
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100552void
553Py_GetArgcArgv(int *argc, wchar_t ***argv)
554{
Victor Stinner74f65682019-03-15 15:08:05 +0100555 *argc = (int)orig_argv.length;
556 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100557}
558
559
Victor Stinner331a6a52019-05-27 16:39:22 +0200560/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100561
562#define DECODE_LOCALE_ERR(NAME, LEN) \
563 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200564 ? _PyStatus_ERR("cannot decode " NAME) \
565 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100566
Victor Stinner441b10c2019-09-28 04:28:35 +0200567
Victor Stinner6c785c02018-08-01 17:56:14 +0200568/* Free memory allocated in config, but don't clear all attributes */
569void
Victor Stinner331a6a52019-05-27 16:39:22 +0200570PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200571{
572#define CLEAR(ATTR) \
573 do { \
574 PyMem_RawFree(ATTR); \
575 ATTR = NULL; \
576 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200577
578 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200579 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200580 CLEAR(config->home);
581 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200582
Victor Stinner331a6a52019-05-27 16:39:22 +0200583 _PyWideStringList_Clear(&config->argv);
584 _PyWideStringList_Clear(&config->warnoptions);
585 _PyWideStringList_Clear(&config->xoptions);
586 _PyWideStringList_Clear(&config->module_search_paths);
587 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200588
589 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700590 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200591 CLEAR(config->prefix);
592 CLEAR(config->base_prefix);
593 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200594 CLEAR(config->base_exec_prefix);
Victor Stinner81750642020-06-08 19:36:13 +0200595 CLEAR(config->platlibdir);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200596
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200597 CLEAR(config->filesystem_encoding);
598 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200599 CLEAR(config->stdio_encoding);
600 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100601 CLEAR(config->run_command);
602 CLEAR(config->run_module);
603 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400604 CLEAR(config->check_hash_pycs_mode);
Miss Islington (bot)bab08332020-06-15 08:19:06 -0700605
606 _PyWideStringList_Clear(&config->_orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200607#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200608}
609
610
Victor Stinner8462a492019-10-01 12:06:16 +0200611void
Victor Stinner331a6a52019-05-27 16:39:22 +0200612_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200613{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200614 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200615
Victor Stinner022be022019-05-22 23:58:50 +0200616 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200617 config->isolated = -1;
618 config->use_environment = -1;
619 config->dev_mode = -1;
620 config->install_signal_handlers = 1;
621 config->use_hash_seed = -1;
622 config->faulthandler = -1;
623 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200624 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200625 config->parse_argv = 0;
626 config->site_import = -1;
627 config->bytes_warning = -1;
628 config->inspect = -1;
629 config->interactive = -1;
630 config->optimization_level = -1;
631 config->parser_debug= -1;
632 config->write_bytecode = -1;
633 config->verbose = -1;
634 config->quiet = -1;
635 config->user_site_directory = -1;
636 config->configure_c_stdio = 0;
637 config->buffered_stdio = -1;
638 config->_install_importlib = 1;
639 config->check_hash_pycs_mode = NULL;
640 config->pathconfig_warnings = -1;
641 config->_init_main = 1;
Victor Stinner252346a2020-05-01 11:33:44 +0200642 config->_isolated_interpreter = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200643#ifdef MS_WINDOWS
644 config->legacy_windows_stdio = -1;
645#endif
Victor Stinner1def7752020-04-23 03:03:24 +0200646 config->_use_peg_parser = 1;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200647}
648
649
Victor Stinner8462a492019-10-01 12:06:16 +0200650static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200651config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200652{
Victor Stinner8462a492019-10-01 12:06:16 +0200653 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200654
655 config->isolated = 0;
656 config->use_environment = 1;
657 config->site_import = 1;
658 config->bytes_warning = 0;
659 config->inspect = 0;
660 config->interactive = 0;
661 config->optimization_level = 0;
662 config->parser_debug= 0;
663 config->write_bytecode = 1;
664 config->verbose = 0;
665 config->quiet = 0;
666 config->user_site_directory = 1;
667 config->buffered_stdio = 1;
668 config->pathconfig_warnings = 1;
669#ifdef MS_WINDOWS
670 config->legacy_windows_stdio = 0;
671#endif
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_InitPythonConfig(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_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200681 config->configure_c_stdio = 1;
682 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200683}
684
685
Victor Stinner8462a492019-10-01 12:06:16 +0200686void
Victor Stinner331a6a52019-05-27 16:39:22 +0200687PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200688{
Victor Stinner8462a492019-10-01 12:06:16 +0200689 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200690
Victor Stinner022be022019-05-22 23:58:50 +0200691 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200692 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200693 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200694 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200695 config->dev_mode = 0;
696 config->install_signal_handlers = 0;
697 config->use_hash_seed = 0;
698 config->faulthandler = 0;
699 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200700 config->pathconfig_warnings = 0;
701#ifdef MS_WINDOWS
702 config->legacy_windows_stdio = 0;
703#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200704}
705
706
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200707/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200708PyStatus
709PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200710{
Victor Stinner331a6a52019-05-27 16:39:22 +0200711 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
712 if (_PyStatus_EXCEPTION(status)) {
713 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200714 }
715
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200716 wchar_t *str2;
717 if (str != NULL) {
718 str2 = _PyMem_RawWcsdup(str);
719 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200720 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200721 }
722 }
723 else {
724 str2 = NULL;
725 }
726 PyMem_RawFree(*config_str);
727 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200728 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200729}
730
731
Victor Stinner331a6a52019-05-27 16:39:22 +0200732static PyStatus
733config_set_bytes_string(PyConfig *config, wchar_t **config_str,
734 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200735{
Victor Stinner331a6a52019-05-27 16:39:22 +0200736 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
737 if (_PyStatus_EXCEPTION(status)) {
738 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400739 }
740
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200741 wchar_t *str2;
742 if (str != NULL) {
743 size_t len;
744 str2 = Py_DecodeLocale(str, &len);
745 if (str2 == NULL) {
746 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200747 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200748 }
749 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200750 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200751 }
752 }
753 }
754 else {
755 str2 = NULL;
756 }
757 PyMem_RawFree(*config_str);
758 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200759 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200760}
761
762
Victor Stinner331a6a52019-05-27 16:39:22 +0200763#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
764 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400765
766
Victor Stinner70005ac2019-05-02 15:25:34 -0400767/* Decode str using Py_DecodeLocale() and set the result into *config_str.
768 Pre-initialize Python if needed to ensure that encodings are properly
769 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200770PyStatus
771PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200772 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400773{
Victor Stinner331a6a52019-05-27 16:39:22 +0200774 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400775}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200776
777
Victor Stinner331a6a52019-05-27 16:39:22 +0200778PyStatus
779_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200780{
Victor Stinner331a6a52019-05-27 16:39:22 +0200781 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200782
Victor Stinner331a6a52019-05-27 16:39:22 +0200783 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200784
785#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200786#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200787 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200788 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
789 if (_PyStatus_EXCEPTION(status)) { \
790 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200791 } \
792 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100793#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200794 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200795 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200796 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200797 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200798 } while (0)
799
Victor Stinner6d1c4672019-05-20 11:02:00 +0200800 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100801 COPY_ATTR(isolated);
802 COPY_ATTR(use_environment);
803 COPY_ATTR(dev_mode);
Victor Stinner1def7752020-04-23 03:03:24 +0200804 COPY_ATTR(_use_peg_parser);
Victor Stinner6c785c02018-08-01 17:56:14 +0200805 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200806 COPY_ATTR(use_hash_seed);
807 COPY_ATTR(hash_seed);
808 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200809 COPY_ATTR(faulthandler);
810 COPY_ATTR(tracemalloc);
811 COPY_ATTR(import_time);
812 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200813 COPY_ATTR(dump_refs);
814 COPY_ATTR(malloc_stats);
815
Victor Stinner124b9eb2018-08-29 01:29:06 +0200816 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200817 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200818 COPY_WSTR_ATTR(home);
819 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200820
Victor Stinnerae239f62019-05-16 17:02:56 +0200821 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100822 COPY_WSTRLIST(argv);
823 COPY_WSTRLIST(warnoptions);
824 COPY_WSTRLIST(xoptions);
825 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200826 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200827
Victor Stinner124b9eb2018-08-29 01:29:06 +0200828 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700829 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200830 COPY_WSTR_ATTR(prefix);
831 COPY_WSTR_ATTR(base_prefix);
832 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200833 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner81750642020-06-08 19:36:13 +0200834 COPY_WSTR_ATTR(platlibdir);
Victor Stinner6c785c02018-08-01 17:56:14 +0200835
Victor Stinner6c785c02018-08-01 17:56:14 +0200836 COPY_ATTR(site_import);
837 COPY_ATTR(bytes_warning);
838 COPY_ATTR(inspect);
839 COPY_ATTR(interactive);
840 COPY_ATTR(optimization_level);
841 COPY_ATTR(parser_debug);
842 COPY_ATTR(write_bytecode);
843 COPY_ATTR(verbose);
844 COPY_ATTR(quiet);
845 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200846 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200847 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400848 COPY_WSTR_ATTR(filesystem_encoding);
849 COPY_WSTR_ATTR(filesystem_errors);
850 COPY_WSTR_ATTR(stdio_encoding);
851 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200852#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200853 COPY_ATTR(legacy_windows_stdio);
854#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100855 COPY_ATTR(skip_source_first_line);
856 COPY_WSTR_ATTR(run_command);
857 COPY_WSTR_ATTR(run_module);
858 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400859 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200860 COPY_ATTR(pathconfig_warnings);
861 COPY_ATTR(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200862 COPY_ATTR(_isolated_interpreter);
Victor Stinnerdedaac02020-06-08 18:44:50 +0200863 COPY_WSTRLIST(_orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200864
865#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200866#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200867#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200868 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200869}
870
871
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100872static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200873config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100874{
875 PyObject *dict;
876
877 dict = PyDict_New();
878 if (dict == NULL) {
879 return NULL;
880 }
881
882#define SET_ITEM(KEY, EXPR) \
883 do { \
884 PyObject *obj = (EXPR); \
885 if (obj == NULL) { \
886 goto fail; \
887 } \
888 int res = PyDict_SetItemString(dict, (KEY), obj); \
889 Py_DECREF(obj); \
890 if (res < 0) { \
891 goto fail; \
892 } \
893 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100894#define SET_ITEM_INT(ATTR) \
895 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
896#define SET_ITEM_UINT(ATTR) \
897 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100898#define FROM_WSTRING(STR) \
899 ((STR != NULL) ? \
900 PyUnicode_FromWideChar(STR, -1) \
901 : (Py_INCREF(Py_None), Py_None))
902#define SET_ITEM_WSTR(ATTR) \
903 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
904#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200905 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100906
Victor Stinner6d1c4672019-05-20 11:02:00 +0200907 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100908 SET_ITEM_INT(isolated);
909 SET_ITEM_INT(use_environment);
910 SET_ITEM_INT(dev_mode);
Victor Stinner1def7752020-04-23 03:03:24 +0200911 SET_ITEM_INT(_use_peg_parser);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100912 SET_ITEM_INT(install_signal_handlers);
913 SET_ITEM_INT(use_hash_seed);
914 SET_ITEM_UINT(hash_seed);
915 SET_ITEM_INT(faulthandler);
916 SET_ITEM_INT(tracemalloc);
917 SET_ITEM_INT(import_time);
918 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100919 SET_ITEM_INT(dump_refs);
920 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400921 SET_ITEM_WSTR(filesystem_encoding);
922 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100923 SET_ITEM_WSTR(pycache_prefix);
924 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200925 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100926 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100927 SET_ITEM_WSTRLIST(xoptions);
928 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200929 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100930 SET_ITEM_WSTR(home);
931 SET_ITEM_WSTRLIST(module_search_paths);
932 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700933 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100934 SET_ITEM_WSTR(prefix);
935 SET_ITEM_WSTR(base_prefix);
936 SET_ITEM_WSTR(exec_prefix);
937 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinner81750642020-06-08 19:36:13 +0200938 SET_ITEM_WSTR(platlibdir);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100939 SET_ITEM_INT(site_import);
940 SET_ITEM_INT(bytes_warning);
941 SET_ITEM_INT(inspect);
942 SET_ITEM_INT(interactive);
943 SET_ITEM_INT(optimization_level);
944 SET_ITEM_INT(parser_debug);
945 SET_ITEM_INT(write_bytecode);
946 SET_ITEM_INT(verbose);
947 SET_ITEM_INT(quiet);
948 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200949 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100950 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400951 SET_ITEM_WSTR(stdio_encoding);
952 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100953#ifdef MS_WINDOWS
954 SET_ITEM_INT(legacy_windows_stdio);
955#endif
956 SET_ITEM_INT(skip_source_first_line);
957 SET_ITEM_WSTR(run_command);
958 SET_ITEM_WSTR(run_module);
959 SET_ITEM_WSTR(run_filename);
960 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400961 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200962 SET_ITEM_INT(pathconfig_warnings);
963 SET_ITEM_INT(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200964 SET_ITEM_INT(_isolated_interpreter);
Victor Stinnerdedaac02020-06-08 18:44:50 +0200965 SET_ITEM_WSTRLIST(_orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100966
967 return dict;
968
969fail:
970 Py_DECREF(dict);
971 return NULL;
972
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100973#undef FROM_WSTRING
974#undef SET_ITEM
975#undef SET_ITEM_INT
976#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100977#undef SET_ITEM_WSTR
978#undef SET_ITEM_WSTRLIST
979}
980
981
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100982static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200983config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200984{
Victor Stinner20004952019-03-26 02:31:11 +0100985 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200986}
987
988
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100989/* Get a copy of the environment variable as wchar_t*.
990 Return 0 on success, but *dest can be NULL.
991 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200992static PyStatus
993config_get_env_dup(PyConfig *config,
994 wchar_t **dest,
995 wchar_t *wname, char *name,
996 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200997{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200998 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100999 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +02001000
Victor Stinner20004952019-03-26 02:31:11 +01001001 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001002 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001003 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001004 }
1005
1006#ifdef MS_WINDOWS
1007 const wchar_t *var = _wgetenv(wname);
1008 if (!var || var[0] == '\0') {
1009 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001010 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001011 }
1012
Victor Stinner331a6a52019-05-27 16:39:22 +02001013 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +02001014#else
1015 const char *var = getenv(name);
1016 if (!var || var[0] == '\0') {
1017 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001018 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001019 }
1020
Victor Stinner331a6a52019-05-27 16:39:22 +02001021 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001022#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001023}
1024
1025
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001026#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001027 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001028
1029
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001030static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001031config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001032{
Victor Stinner022be022019-05-22 23:58:50 +02001033 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1034 /* Python and Isolated configuration ignore global variables */
1035 return;
1036 }
1037
Victor Stinner6c785c02018-08-01 17:56:14 +02001038#define COPY_FLAG(ATTR, VALUE) \
1039 if (config->ATTR == -1) { \
1040 config->ATTR = VALUE; \
1041 }
1042#define COPY_NOT_FLAG(ATTR, VALUE) \
1043 if (config->ATTR == -1) { \
1044 config->ATTR = !(VALUE); \
1045 }
1046
Victor Stinner20004952019-03-26 02:31:11 +01001047 COPY_FLAG(isolated, Py_IsolatedFlag);
1048 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001049 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1050 COPY_FLAG(inspect, Py_InspectFlag);
1051 COPY_FLAG(interactive, Py_InteractiveFlag);
1052 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1053 COPY_FLAG(parser_debug, Py_DebugFlag);
1054 COPY_FLAG(verbose, Py_VerboseFlag);
1055 COPY_FLAG(quiet, Py_QuietFlag);
1056#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001057 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1058#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001059 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001060
Victor Stinner6c785c02018-08-01 17:56:14 +02001061 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1062 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1063 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1064 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1065
Victor Stinner6c785c02018-08-01 17:56:14 +02001066#undef COPY_FLAG
1067#undef COPY_NOT_FLAG
1068}
1069
1070
1071/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001072static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001073config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001074{
1075#define COPY_FLAG(ATTR, VAR) \
1076 if (config->ATTR != -1) { \
1077 VAR = config->ATTR; \
1078 }
1079#define COPY_NOT_FLAG(ATTR, VAR) \
1080 if (config->ATTR != -1) { \
1081 VAR = !config->ATTR; \
1082 }
1083
Victor Stinner20004952019-03-26 02:31:11 +01001084 COPY_FLAG(isolated, Py_IsolatedFlag);
1085 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001086 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1087 COPY_FLAG(inspect, Py_InspectFlag);
1088 COPY_FLAG(interactive, Py_InteractiveFlag);
1089 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1090 COPY_FLAG(parser_debug, Py_DebugFlag);
1091 COPY_FLAG(verbose, Py_VerboseFlag);
1092 COPY_FLAG(quiet, Py_QuietFlag);
1093#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001094 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1095#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001096 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001097
Victor Stinner6c785c02018-08-01 17:56:14 +02001098 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1099 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1100 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1101 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1102
Victor Stinner6c785c02018-08-01 17:56:14 +02001103 /* Random or non-zero hash seed */
1104 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1105 config->hash_seed != 0);
1106
1107#undef COPY_FLAG
1108#undef COPY_NOT_FLAG
1109}
1110
1111
1112/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1113 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001114static PyStatus
1115config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001116{
Victor Stinner331a6a52019-05-27 16:39:22 +02001117 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001118
Victor Stinner6c785c02018-08-01 17:56:14 +02001119 /* If Py_SetProgramName() was called, use its value */
1120 const wchar_t *program_name = _Py_path_config.program_name;
1121 if (program_name != NULL) {
1122 config->program_name = _PyMem_RawWcsdup(program_name);
1123 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001124 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001125 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001126 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001127 }
1128
1129#ifdef __APPLE__
1130 /* On MacOS X, when the Python interpreter is embedded in an
1131 application bundle, it gets executed by a bootstrapping script
1132 that does os.execve() with an argv[0] that's different from the
1133 actual Python executable. This is needed to keep the Finder happy,
1134 or rather, to work around Apple's overly strict requirements of
1135 the process name. However, we still need a usable sys.executable,
1136 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001137 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001138 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001139 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001140 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001141 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1142 "PYTHONEXECUTABLE environment variable");
1143 if (_PyStatus_EXCEPTION(status)) {
1144 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001145 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001146 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001147 }
1148#ifdef WITH_NEXT_FRAMEWORK
1149 else {
1150 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1151 if (pyvenv_launcher && *pyvenv_launcher) {
1152 /* Used by Mac/Tools/pythonw.c to forward
1153 * the argv0 of the stub executable
1154 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001155 status = CONFIG_SET_BYTES_STR(config,
1156 &config->program_name,
1157 pyvenv_launcher,
1158 "__PYVENV_LAUNCHER__ environment variable");
1159 if (_PyStatus_EXCEPTION(status)) {
1160 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001161 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001162
1163 /*
1164 * This environment variable is used to communicate between
1165 * the stub launcher and the real interpreter and isn't needed
1166 * beyond this point.
1167 *
1168 * Clean up to avoid problems when launching other programs
1169 * later on.
1170 */
1171 (void)unsetenv("__PYVENV_LAUNCHER__");
1172
Victor Stinner331a6a52019-05-27 16:39:22 +02001173 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001174 }
1175 }
1176#endif /* WITH_NEXT_FRAMEWORK */
1177#endif /* __APPLE__ */
1178
Victor Stinnerfed02e12019-05-17 11:12:09 +02001179 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001180 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001181 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1182 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1183 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001184 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001185 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001186 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001187 }
1188
Victor Stinnerfed02e12019-05-17 11:12:09 +02001189 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001190#ifdef MS_WINDOWS
1191 const wchar_t *default_program_name = L"python";
1192#else
1193 const wchar_t *default_program_name = L"python3";
1194#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001195 status = PyConfig_SetString(config, &config->program_name,
1196 default_program_name);
1197 if (_PyStatus_EXCEPTION(status)) {
1198 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001199 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001200 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001201}
1202
Victor Stinner331a6a52019-05-27 16:39:22 +02001203static PyStatus
1204config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001205{
1206 assert(config->executable == NULL);
1207
1208 /* If Py_SetProgramFullPath() was called, use its value */
1209 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1210 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001211 PyStatus status = PyConfig_SetString(config,
1212 &config->executable,
1213 program_full_path);
1214 if (_PyStatus_EXCEPTION(status)) {
1215 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001216 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001217 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001218 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001219 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001220}
Victor Stinner6c785c02018-08-01 17:56:14 +02001221
Victor Stinner4fffd382019-03-06 01:44:31 +01001222
Victor Stinner6c785c02018-08-01 17:56:14 +02001223static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001224config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001225{
Victor Stinner74f65682019-03-15 15:08:05 +01001226 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001227}
1228
1229
Victor Stinner331a6a52019-05-27 16:39:22 +02001230static PyStatus
1231config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001232{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001233 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001234
1235 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001236 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001237 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001238 PyStatus status = PyConfig_SetString(config, &config->home, home);
1239 if (_PyStatus_EXCEPTION(status)) {
1240 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001241 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001242 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001243 }
1244
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001245 return CONFIG_GET_ENV_DUP(config, &config->home,
1246 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001247}
1248
1249
Victor Stinner331a6a52019-05-27 16:39:22 +02001250static PyStatus
1251config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001252{
Victor Stinner331a6a52019-05-27 16:39:22 +02001253 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001254
1255 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1256 /* Convert a text seed to a numeric one */
1257 if (seed_text && strcmp(seed_text, "random") != 0) {
1258 const char *endptr = seed_text;
1259 unsigned long seed;
1260 errno = 0;
1261 seed = strtoul(seed_text, (char **)&endptr, 10);
1262 if (*endptr != '\0'
1263 || seed > 4294967295UL
1264 || (errno == ERANGE && seed == ULONG_MAX))
1265 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001266 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001267 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001268 }
1269 /* Use a specific hash */
1270 config->use_hash_seed = 1;
1271 config->hash_seed = seed;
1272 }
1273 else {
1274 /* Use a random hash */
1275 config->use_hash_seed = 0;
1276 config->hash_seed = 0;
1277 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001278 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001279}
1280
1281
Victor Stinner6c785c02018-08-01 17:56:14 +02001282static int
1283config_wstr_to_int(const wchar_t *wstr, int *result)
1284{
1285 const wchar_t *endptr = wstr;
1286 errno = 0;
1287 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1288 if (*endptr != '\0' || errno == ERANGE) {
1289 return -1;
1290 }
1291 if (value < INT_MIN || value > INT_MAX) {
1292 return -1;
1293 }
1294
1295 *result = (int)value;
1296 return 0;
1297}
1298
1299
Victor Stinner331a6a52019-05-27 16:39:22 +02001300static PyStatus
1301config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001302{
Victor Stinner331a6a52019-05-27 16:39:22 +02001303 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001304 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001305
Victor Stinner6c785c02018-08-01 17:56:14 +02001306 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001307 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1308 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1309 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1310 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001311
1312 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001313 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001314 if (dont_write_bytecode) {
1315 config->write_bytecode = 0;
1316 }
1317
1318 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001319 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001320 if (no_user_site_directory) {
1321 config->user_site_directory = 0;
1322 }
1323
1324 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001325 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001326 if (unbuffered_stdio) {
1327 config->buffered_stdio = 0;
1328 }
1329
1330#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001331 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001332 "PYTHONLEGACYWINDOWSSTDIO");
1333#endif
1334
Victor Stinner331a6a52019-05-27 16:39:22 +02001335 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001336 config->dump_refs = 1;
1337 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001338 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001339 config->malloc_stats = 1;
1340 }
1341
Victor Stinner331a6a52019-05-27 16:39:22 +02001342 if (config->pythonpath_env == NULL) {
1343 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1344 L"PYTHONPATH", "PYTHONPATH");
1345 if (_PyStatus_EXCEPTION(status)) {
1346 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001347 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001348 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001349
Victor Stinner81750642020-06-08 19:36:13 +02001350 if(config->platlibdir == NULL) {
1351 status = CONFIG_GET_ENV_DUP(config, &config->platlibdir,
1352 L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR");
1353 if (_PyStatus_EXCEPTION(status)) {
1354 return status;
1355 }
1356 }
1357
Victor Stinner6c785c02018-08-01 17:56:14 +02001358 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001359 status = config_init_hash_seed(config);
1360 if (_PyStatus_EXCEPTION(status)) {
1361 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001362 }
1363 }
1364
Victor Stinner331a6a52019-05-27 16:39:22 +02001365 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001366}
1367
1368
Victor Stinner331a6a52019-05-27 16:39:22 +02001369static PyStatus
1370config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001371{
1372 int nframe;
1373 int valid;
1374
Victor Stinner331a6a52019-05-27 16:39:22 +02001375 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001376 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001377 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001378 valid = (nframe >= 0);
1379 }
1380 else {
1381 valid = 0;
1382 }
1383 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001384 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001385 }
1386 config->tracemalloc = nframe;
1387 }
1388
1389 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1390 if (xoption) {
1391 const wchar_t *sep = wcschr(xoption, L'=');
1392 if (sep) {
1393 if (!config_wstr_to_int(sep + 1, &nframe)) {
1394 valid = (nframe >= 0);
1395 }
1396 else {
1397 valid = 0;
1398 }
1399 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001400 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1401 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001402 }
1403 }
1404 else {
1405 /* -X tracemalloc behaves as -X tracemalloc=1 */
1406 nframe = 1;
1407 }
1408 config->tracemalloc = nframe;
1409 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001410 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001411}
1412
1413
Victor Stinner331a6a52019-05-27 16:39:22 +02001414static PyStatus
1415config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001416{
1417 assert(config->pycache_prefix == NULL);
1418
1419 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1420 if (xoption) {
1421 const wchar_t *sep = wcschr(xoption, L'=');
1422 if (sep && wcslen(sep) > 1) {
1423 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1424 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001425 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001426 }
1427 }
1428 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001429 // PYTHONPYCACHEPREFIX env var ignored
1430 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001431 config->pycache_prefix = NULL;
1432 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001433 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001434 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001435
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001436 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1437 L"PYTHONPYCACHEPREFIX",
1438 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001439}
1440
1441
Victor Stinner331a6a52019-05-27 16:39:22 +02001442static PyStatus
1443config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001444{
1445 /* More complex options configured by env var and -X option */
1446 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001447 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001448 || config_get_xoption(config, L"faulthandler")) {
1449 config->faulthandler = 1;
1450 }
1451 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001452 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001453 || config_get_xoption(config, L"importtime")) {
1454 config->import_time = 1;
1455 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001456
Pablo Galindoc5fc1562020-04-22 23:29:27 +01001457 if (config_get_env(config, "PYTHONOLDPARSER")
1458 || config_get_xoption(config, L"oldparser")) {
Victor Stinner1def7752020-04-23 03:03:24 +02001459 config->_use_peg_parser = 0;
Pablo Galindoc5fc1562020-04-22 23:29:27 +01001460 }
1461
Victor Stinner331a6a52019-05-27 16:39:22 +02001462 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001463 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001464 status = config_init_tracemalloc(config);
1465 if (_PyStatus_EXCEPTION(status)) {
1466 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001467 }
1468 }
1469
1470 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001471 status = config_init_pycache_prefix(config);
1472 if (_PyStatus_EXCEPTION(status)) {
1473 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001474 }
1475 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001476 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001477}
1478
1479
Victor Stinner709d23d2019-05-02 14:56:30 -04001480static const wchar_t *
Andy Lesteraa450a02020-03-07 11:36:04 -06001481config_get_stdio_errors(void)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001482{
1483#ifndef MS_WINDOWS
1484 const char *loc = setlocale(LC_CTYPE, NULL);
1485 if (loc != NULL) {
1486 /* surrogateescape is the default in the legacy C and POSIX locales */
1487 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001488 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001489 }
1490
1491#ifdef PY_COERCE_C_LOCALE
1492 /* surrogateescape is the default in locale coercion target locales */
1493 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001494 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001495 }
1496#endif
1497 }
1498
Victor Stinner709d23d2019-05-02 14:56:30 -04001499 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001500#else
1501 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001502 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001503#endif
1504}
1505
1506
Victor Stinner331a6a52019-05-27 16:39:22 +02001507static PyStatus
1508config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001509{
1510#ifdef MS_WINDOWS
1511 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001512 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001513 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001514#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001515 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001516#else
1517 const char *encoding = nl_langinfo(CODESET);
1518 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001519 return _PyStatus_ERR("failed to get the locale encoding: "
1520 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001521 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001522 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001523 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001524 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001525 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001526#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001527}
1528
1529
Victor Stinner331a6a52019-05-27 16:39:22 +02001530static PyStatus
1531config_init_stdio_encoding(PyConfig *config,
1532 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001533{
Victor Stinner331a6a52019-05-27 16:39:22 +02001534 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001535
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001536 /* If Py_SetStandardStreamEncoding() have been called, use these
1537 parameters. */
1538 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001539 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1540 _Py_StandardStreamEncoding,
1541 "_Py_StandardStreamEncoding");
1542 if (_PyStatus_EXCEPTION(status)) {
1543 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001544 }
1545 }
1546
1547 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001548 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1549 _Py_StandardStreamErrors,
1550 "_Py_StandardStreamErrors");
1551 if (_PyStatus_EXCEPTION(status)) {
1552 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001553 }
1554 }
1555
1556 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001557 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001558 }
1559
1560 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001561 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001562 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001563 char *pythonioencoding = _PyMem_RawStrdup(opt);
1564 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001565 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001566 }
1567
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001568 char *errors = strchr(pythonioencoding, ':');
1569 if (errors) {
1570 *errors = '\0';
1571 errors++;
1572 if (!errors[0]) {
1573 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001574 }
1575 }
1576
1577 /* Does PYTHONIOENCODING contain an encoding? */
1578 if (pythonioencoding[0]) {
1579 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001580 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1581 pythonioencoding,
1582 "PYTHONIOENCODING environment variable");
1583 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001584 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001585 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001586 }
1587 }
1588
1589 /* If the encoding is set but not the error handler,
1590 use "strict" error handler by default.
1591 PYTHONIOENCODING=latin1 behaves as
1592 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001593 if (!errors) {
1594 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001595 }
1596 }
1597
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001598 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001599 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1600 errors,
1601 "PYTHONIOENCODING environment variable");
1602 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001603 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001604 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001605 }
1606 }
1607
1608 PyMem_RawFree(pythonioencoding);
1609 }
1610
1611 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001612 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001613 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001614 status = PyConfig_SetString(config, &config->stdio_encoding,
1615 L"utf-8");
1616 if (_PyStatus_EXCEPTION(status)) {
1617 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001618 }
1619 }
1620 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001621 status = PyConfig_SetString(config, &config->stdio_errors,
1622 L"surrogateescape");
1623 if (_PyStatus_EXCEPTION(status)) {
1624 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001625 }
1626 }
1627 }
1628
1629 /* Choose the default error handler based on the current locale. */
1630 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001631 status = config_get_locale_encoding(config, &config->stdio_encoding);
1632 if (_PyStatus_EXCEPTION(status)) {
1633 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001634 }
1635 }
1636 if (config->stdio_errors == NULL) {
Andy Lesteraa450a02020-03-07 11:36:04 -06001637 const wchar_t *errors = config_get_stdio_errors();
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001638 assert(errors != NULL);
1639
Victor Stinner331a6a52019-05-27 16:39:22 +02001640 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1641 if (_PyStatus_EXCEPTION(status)) {
1642 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001643 }
1644 }
1645
Victor Stinner331a6a52019-05-27 16:39:22 +02001646 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001647}
1648
1649
Victor Stinner331a6a52019-05-27 16:39:22 +02001650static PyStatus
1651config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001652{
Victor Stinner331a6a52019-05-27 16:39:22 +02001653 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001654
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001655 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001656#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001657 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001658#else
Victor Stinnere2510952019-05-02 11:28:57 -04001659
1660#ifdef MS_WINDOWS
1661 if (preconfig->legacy_windows_fs_encoding) {
1662 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001663 status = PyConfig_SetString(config, &config->filesystem_encoding,
1664 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001665 }
1666 else
1667#endif
Victor Stinner20004952019-03-26 02:31:11 +01001668 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001669 status = PyConfig_SetString(config, &config->filesystem_encoding,
1670 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001671 }
Victor Stinnere2510952019-05-02 11:28:57 -04001672#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001673 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001674 status = PyConfig_SetString(config, &config->filesystem_encoding,
1675 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001676 }
Victor Stinnere2510952019-05-02 11:28:57 -04001677#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001678 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001679#ifdef MS_WINDOWS
1680 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001681 status = PyConfig_SetString(config, &config->filesystem_encoding,
1682 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001683#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001684 status = config_get_locale_encoding(config,
1685 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001686#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001687 }
Victor Stinnere2510952019-05-02 11:28:57 -04001688#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001689
Victor Stinner331a6a52019-05-27 16:39:22 +02001690 if (_PyStatus_EXCEPTION(status)) {
1691 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001692 }
1693 }
1694
1695 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001696 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001697#ifdef MS_WINDOWS
1698 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001699 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001700 }
1701 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001702 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001703 }
1704#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001705 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001706#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001707 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1708 if (_PyStatus_EXCEPTION(status)) {
1709 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001710 }
1711 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001712 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001713}
1714
1715
Victor Stinner331a6a52019-05-27 16:39:22 +02001716static PyStatus
1717config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001718{
Victor Stinner331a6a52019-05-27 16:39:22 +02001719 PyStatus status;
1720 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001721
Victor Stinner20004952019-03-26 02:31:11 +01001722 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001723 status = config_read_env_vars(config);
1724 if (_PyStatus_EXCEPTION(status)) {
1725 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001726 }
1727 }
1728
1729 /* -X options */
1730 if (config_get_xoption(config, L"showrefcount")) {
1731 config->show_ref_count = 1;
1732 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001733
Victor Stinner331a6a52019-05-27 16:39:22 +02001734 status = config_read_complex_options(config);
1735 if (_PyStatus_EXCEPTION(status)) {
1736 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001737 }
1738
Victor Stinner6c785c02018-08-01 17:56:14 +02001739 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001740 status = config_init_home(config);
1741 if (_PyStatus_EXCEPTION(status)) {
1742 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001743 }
1744 }
1745
Steve Dower177a41a2018-11-17 20:41:48 -08001746 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001747 status = config_init_executable(config);
1748 if (_PyStatus_EXCEPTION(status)) {
1749 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001750 }
1751 }
1752
Victor Stinner81750642020-06-08 19:36:13 +02001753 if(config->platlibdir == NULL) {
1754 status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR,
1755 "PLATLIBDIR macro");
1756 if (_PyStatus_EXCEPTION(status)) {
1757 return status;
1758 }
1759 }
1760
Victor Stinner6c785c02018-08-01 17:56:14 +02001761 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001762 status = _PyConfig_InitPathConfig(config);
1763 if (_PyStatus_EXCEPTION(status)) {
1764 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001765 }
1766 }
1767
1768 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001769 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001770 if (config->faulthandler < 0) {
1771 config->faulthandler = 1;
1772 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001773 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001774 if (config->faulthandler < 0) {
1775 config->faulthandler = 0;
1776 }
1777 if (config->tracemalloc < 0) {
1778 config->tracemalloc = 0;
1779 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001780 if (config->use_hash_seed < 0) {
1781 config->use_hash_seed = 0;
1782 config->hash_seed = 0;
1783 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001784
Victor Stinner70fead22018-08-29 13:45:34 +02001785 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001786 status = config_init_fs_encoding(config, preconfig);
1787 if (_PyStatus_EXCEPTION(status)) {
1788 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001789 }
1790 }
1791
Victor Stinner331a6a52019-05-27 16:39:22 +02001792 status = config_init_stdio_encoding(config, preconfig);
1793 if (_PyStatus_EXCEPTION(status)) {
1794 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001795 }
1796
Victor Stinner62599762019-03-15 16:03:23 +01001797 if (config->argv.length < 1) {
1798 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001799 status = PyWideStringList_Append(&config->argv, L"");
1800 if (_PyStatus_EXCEPTION(status)) {
1801 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001802 }
1803 }
Victor Stinner870b0352019-05-17 03:15:12 +02001804
1805 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001806 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1807 L"default");
1808 if (_PyStatus_EXCEPTION(status)) {
1809 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001810 }
1811 }
1812
1813 if (config->configure_c_stdio < 0) {
1814 config->configure_c_stdio = 1;
1815 }
1816
Victor Stinner331a6a52019-05-27 16:39:22 +02001817 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001818}
Victor Stinner5ed69952018-11-06 15:59:52 +01001819
1820
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001821static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001822config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001823{
1824#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1825 /* don't translate newlines (\r\n <=> \n) */
1826 _setmode(fileno(stdin), O_BINARY);
1827 _setmode(fileno(stdout), O_BINARY);
1828 _setmode(fileno(stderr), O_BINARY);
1829#endif
1830
1831 if (!config->buffered_stdio) {
1832#ifdef HAVE_SETVBUF
1833 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1834 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1835 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1836#else /* !HAVE_SETVBUF */
1837 setbuf(stdin, (char *)NULL);
1838 setbuf(stdout, (char *)NULL);
1839 setbuf(stderr, (char *)NULL);
1840#endif /* !HAVE_SETVBUF */
1841 }
1842 else if (config->interactive) {
1843#ifdef MS_WINDOWS
1844 /* Doesn't have to have line-buffered -- use unbuffered */
1845 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1846 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1847#else /* !MS_WINDOWS */
1848#ifdef HAVE_SETVBUF
1849 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1850 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1851#endif /* HAVE_SETVBUF */
1852#endif /* !MS_WINDOWS */
1853 /* Leave stderr alone - it should be unbuffered anyway. */
1854 }
1855}
1856
1857
1858/* Write the configuration:
1859
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001860 - set Py_xxx global configuration variables
1861 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinnerdedaac02020-06-08 18:44:50 +02001862PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +02001863_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001864{
Victor Stinner331a6a52019-05-27 16:39:22 +02001865 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001866
1867 if (config->configure_c_stdio) {
1868 config_init_stdio(config);
1869 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001870
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001871 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001872 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001873 preconfig->isolated = config->isolated;
1874 preconfig->use_environment = config->use_environment;
1875 preconfig->dev_mode = config->dev_mode;
Victor Stinnerdedaac02020-06-08 18:44:50 +02001876
1877 if (_Py_SetArgcArgv(config->_orig_argv.length,
1878 config->_orig_argv.items) < 0)
1879 {
1880 return _PyStatus_NO_MEMORY();
1881 }
1882 return _PyStatus_OK();
Victor Stinner5ed69952018-11-06 15:59:52 +01001883}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001884
1885
Victor Stinner331a6a52019-05-27 16:39:22 +02001886/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001887
1888static void
Victor Stinner2f549082019-03-29 15:13:46 +01001889config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001890{
Victor Stinner2f549082019-03-29 15:13:46 +01001891 FILE *f = error ? stderr : stdout;
1892
1893 fprintf(f, usage_line, program);
1894 if (error)
1895 fprintf(f, "Try `python -h' for more information.\n");
1896 else {
1897 fputs(usage_1, f);
1898 fputs(usage_2, f);
1899 fputs(usage_3, f);
1900 fprintf(f, usage_4, (wint_t)DELIM);
1901 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1902 fputs(usage_6, f);
1903 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001904}
1905
1906
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001907/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001908static PyStatus
1909config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001910 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001911{
Victor Stinner331a6a52019-05-27 16:39:22 +02001912 PyStatus status;
1913 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001914 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001915 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001916
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001917 _PyOS_ResetGetOpt();
1918 do {
1919 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001920 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001921 if (c == EOF) {
1922 break;
1923 }
1924
1925 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001926 if (config->run_command == NULL) {
1927 /* -c is the last option; following arguments
1928 that look like options are left for the
1929 command to interpret. */
1930 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1931 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1932 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001933 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001934 }
1935 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1936 command[len - 2] = '\n';
1937 command[len - 1] = 0;
1938 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001939 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001940 break;
1941 }
1942
1943 if (c == 'm') {
1944 /* -m is the last option; following arguments
1945 that look like options are left for the
1946 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001947 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001948 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1949 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001950 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001951 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001952 }
1953 break;
1954 }
1955
1956 switch (c) {
1957 case 0:
1958 // Handle long option.
1959 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001960 if (wcscmp(_PyOS_optarg, L"always") == 0
1961 || wcscmp(_PyOS_optarg, L"never") == 0
1962 || wcscmp(_PyOS_optarg, L"default") == 0)
1963 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001964 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1965 _PyOS_optarg);
1966 if (_PyStatus_EXCEPTION(status)) {
1967 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001968 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001969 } else {
1970 fprintf(stderr, "--check-hash-based-pycs must be one of "
1971 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001972 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001973 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001974 }
1975 break;
1976
1977 case 'b':
1978 config->bytes_warning++;
1979 break;
1980
1981 case 'd':
1982 config->parser_debug++;
1983 break;
1984
1985 case 'i':
1986 config->inspect++;
1987 config->interactive++;
1988 break;
1989
Victor Stinner6dcb5422019-03-05 02:44:12 +01001990 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001991 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001992 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001993 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001994 break;
1995
1996 /* case 'J': reserved for Jython */
1997
1998 case 'O':
1999 config->optimization_level++;
2000 break;
2001
2002 case 'B':
2003 config->write_bytecode = 0;
2004 break;
2005
2006 case 's':
2007 config->user_site_directory = 0;
2008 break;
2009
2010 case 'S':
2011 config->site_import = 0;
2012 break;
2013
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002014 case 't':
2015 /* ignored for backwards compatibility */
2016 break;
2017
2018 case 'u':
2019 config->buffered_stdio = 0;
2020 break;
2021
2022 case 'v':
2023 config->verbose++;
2024 break;
2025
2026 case 'x':
2027 config->skip_source_first_line = 1;
2028 break;
2029
2030 case 'h':
2031 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02002032 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002033 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002034
2035 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01002036 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002037 break;
2038
2039 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002040 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2041 if (_PyStatus_EXCEPTION(status)) {
2042 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002043 }
2044 break;
2045
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002046 case 'q':
2047 config->quiet++;
2048 break;
2049
2050 case 'R':
2051 config->use_hash_seed = 0;
2052 break;
2053
2054 /* This space reserved for other options */
2055
2056 default:
2057 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002058 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002059 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002060 }
2061 } while (1);
2062
Victor Stinner2f549082019-03-29 15:13:46 +01002063 if (print_version) {
2064 printf("Python %s\n",
2065 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002066 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002067 }
2068
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002069 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002070 && _PyOS_optind < argv->length
2071 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002072 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002073 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002074 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002075 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002076 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002077 }
2078 }
2079
2080 if (config->run_command != NULL || config->run_module != NULL) {
2081 /* Backup _PyOS_optind */
2082 _PyOS_optind--;
2083 }
2084
Victor Stinnerae239f62019-05-16 17:02:56 +02002085 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002086
Victor Stinner331a6a52019-05-27 16:39:22 +02002087 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002088}
2089
2090
2091#ifdef MS_WINDOWS
2092# define WCSTOK wcstok_s
2093#else
2094# define WCSTOK wcstok
2095#endif
2096
2097/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002098static PyStatus
2099config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002100{
Victor Stinner331a6a52019-05-27 16:39:22 +02002101 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002102 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2103 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002104 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002105 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002106 if (_PyStatus_EXCEPTION(status)) {
2107 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002108 }
2109
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002110 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002111 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002112 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002113 }
2114
2115
2116 wchar_t *warning, *context = NULL;
2117 for (warning = WCSTOK(env, L",", &context);
2118 warning != NULL;
2119 warning = WCSTOK(NULL, L",", &context))
2120 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002121 status = PyWideStringList_Append(warnoptions, warning);
2122 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002123 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002124 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002125 }
2126 }
2127 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002128 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002129}
2130
2131
Victor Stinner331a6a52019-05-27 16:39:22 +02002132static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002133warnoptions_append(PyConfig *config, PyWideStringList *options,
2134 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002135{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002136 /* config_init_warnoptions() add existing config warnoptions at the end:
2137 ensure that the new option is not already present in this list to
2138 prevent change the options order whne config_init_warnoptions() is
2139 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002140 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002141 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002142 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002143 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002144 if (_PyWideStringList_Find(options, option)) {
2145 /* Already present: do nothing */
2146 return _PyStatus_OK();
2147 }
2148 return PyWideStringList_Append(options, option);
2149}
2150
2151
2152static PyStatus
2153warnoptions_extend(PyConfig *config, PyWideStringList *options,
2154 const PyWideStringList *options2)
2155{
2156 const Py_ssize_t len = options2->length;
2157 wchar_t *const *items = options2->items;
2158
2159 for (Py_ssize_t i = 0; i < len; i++) {
2160 PyStatus status = warnoptions_append(config, options, items[i]);
2161 if (_PyStatus_EXCEPTION(status)) {
2162 return status;
2163 }
2164 }
2165 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002166}
2167
2168
Victor Stinner331a6a52019-05-27 16:39:22 +02002169static PyStatus
2170config_init_warnoptions(PyConfig *config,
2171 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002172 const PyWideStringList *env_warnoptions,
2173 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002174{
Victor Stinner331a6a52019-05-27 16:39:22 +02002175 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002176 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002177
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002178 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002179 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002180 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002181 * - PyConfig.dev_mode: "default" filter
2182 * - PYTHONWARNINGS environment variable
2183 * - '-W' command line options
2184 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2185 * "default::BytesWarning" or "error::BytesWarning" filter
2186 * - early PySys_AddWarnOption() calls
2187 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002188 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002189 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2190 * module works on the basis of "the most recently added filter will be
2191 * checked first", we add the lowest precedence entries first so that later
2192 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002193 */
2194
Victor Stinner20004952019-03-26 02:31:11 +01002195 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002196 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002197 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002198 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002199 }
2200 }
2201
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002202 status = warnoptions_extend(config, &options, env_warnoptions);
2203 if (_PyStatus_EXCEPTION(status)) {
2204 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002205 }
2206
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002207 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2208 if (_PyStatus_EXCEPTION(status)) {
2209 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002210 }
2211
2212 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2213 * don't even try to emit a warning, so we skip setting the filter in that
2214 * case.
2215 */
2216 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002217 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002218 if (config->bytes_warning> 1) {
2219 filter = L"error::BytesWarning";
2220 }
2221 else {
2222 filter = L"default::BytesWarning";
2223 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002224 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002225 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002226 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002227 }
2228 }
Victor Stinner120b7072019-08-23 18:03:08 +01002229
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002230 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002231 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002232 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002233 }
2234
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002235 /* Always add all PyConfig.warnoptions options */
2236 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2237 if (_PyStatus_EXCEPTION(status)) {
2238 goto error;
2239 }
2240
2241 _PyWideStringList_Clear(&config->warnoptions);
2242 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002243 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002244
2245error:
2246 _PyWideStringList_Clear(&options);
2247 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002248}
2249
2250
Victor Stinner331a6a52019-05-27 16:39:22 +02002251static PyStatus
2252config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002253{
Victor Stinner331a6a52019-05-27 16:39:22 +02002254 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002255 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002256
Victor Stinner74f65682019-03-15 15:08:05 +01002257 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002258 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002259 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002260 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2261 if (_PyStatus_EXCEPTION(status)) {
2262 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002263 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002264 }
2265 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002266 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002267 slice.length = cmdline_argv->length - opt_index;
2268 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002269 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2270 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002271 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002272 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002273 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002274
2275 wchar_t *arg0 = NULL;
2276 if (config->run_command != NULL) {
2277 /* Force sys.argv[0] = '-c' */
2278 arg0 = L"-c";
2279 }
2280 else if (config->run_module != NULL) {
2281 /* Force sys.argv[0] = '-m'*/
2282 arg0 = L"-m";
2283 }
Victor Stinner3939c322019-06-25 15:02:43 +02002284
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002285 if (arg0 != NULL) {
2286 arg0 = _PyMem_RawWcsdup(arg0);
2287 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002288 _PyWideStringList_Clear(&config_argv);
2289 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002290 }
2291
Victor Stinnerfa153762019-03-20 04:25:38 +01002292 PyMem_RawFree(config_argv.items[0]);
2293 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002294 }
2295
Victor Stinner331a6a52019-05-27 16:39:22 +02002296 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002297 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002298 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002299}
2300
2301
Victor Stinner331a6a52019-05-27 16:39:22 +02002302static PyStatus
2303core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002304{
Victor Stinner331a6a52019-05-27 16:39:22 +02002305 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002306
Victor Stinnercab5d072019-05-17 19:01:14 +02002307 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002308 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2309 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002310 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002311 }
2312
Victor Stinner331a6a52019-05-27 16:39:22 +02002313 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002314
2315 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2316 if (_PyStatus_EXCEPTION(status)) {
2317 return status;
2318 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002319
Victor Stinner331a6a52019-05-27 16:39:22 +02002320 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002321
Victor Stinner331a6a52019-05-27 16:39:22 +02002322 status = _PyPreCmdline_Read(precmdline, &preconfig);
2323 if (_PyStatus_EXCEPTION(status)) {
2324 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002325 }
2326
Victor Stinner331a6a52019-05-27 16:39:22 +02002327 status = _PyPreCmdline_SetConfig(precmdline, config);
2328 if (_PyStatus_EXCEPTION(status)) {
2329 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002330 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002331 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002332}
2333
2334
Victor Stinner3939c322019-06-25 15:02:43 +02002335/* Get run_filename absolute path */
2336static PyStatus
2337config_run_filename_abspath(PyConfig *config)
2338{
2339 if (!config->run_filename) {
2340 return _PyStatus_OK();
2341 }
2342
2343#ifndef MS_WINDOWS
2344 if (_Py_isabs(config->run_filename)) {
2345 /* path is already absolute */
2346 return _PyStatus_OK();
2347 }
2348#endif
2349
2350 wchar_t *abs_filename;
2351 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2352 /* failed to get the absolute path of the command line filename:
2353 ignore the error, keep the relative path */
2354 return _PyStatus_OK();
2355 }
2356 if (abs_filename == NULL) {
2357 return _PyStatus_NO_MEMORY();
2358 }
2359
2360 PyMem_RawFree(config->run_filename);
2361 config->run_filename = abs_filename;
2362 return _PyStatus_OK();
2363}
2364
2365
Victor Stinner331a6a52019-05-27 16:39:22 +02002366static PyStatus
2367config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002368{
Victor Stinner331a6a52019-05-27 16:39:22 +02002369 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002370 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2371 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2372 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002373
Victor Stinnerae239f62019-05-16 17:02:56 +02002374 if (config->parse_argv < 0) {
2375 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002376 }
Victor Stinner870b0352019-05-17 03:15:12 +02002377
Victor Stinnerfed02e12019-05-17 11:12:09 +02002378 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002379 status = config_init_program_name(config);
2380 if (_PyStatus_EXCEPTION(status)) {
2381 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002382 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002383 }
Victor Stinner2f549082019-03-29 15:13:46 +01002384
Victor Stinnerae239f62019-05-16 17:02:56 +02002385 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002386 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002387 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2388 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002389 goto done;
2390 }
2391
Victor Stinner3939c322019-06-25 15:02:43 +02002392 status = config_run_filename_abspath(config);
2393 if (_PyStatus_EXCEPTION(status)) {
2394 goto done;
2395 }
2396
Victor Stinner331a6a52019-05-27 16:39:22 +02002397 status = config_update_argv(config, opt_index);
2398 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002399 goto done;
2400 }
Victor Stinner2f549082019-03-29 15:13:46 +01002401 }
Victor Stinner3939c322019-06-25 15:02:43 +02002402 else {
2403 status = config_run_filename_abspath(config);
2404 if (_PyStatus_EXCEPTION(status)) {
2405 goto done;
2406 }
2407 }
Victor Stinner2f549082019-03-29 15:13:46 +01002408
Victor Stinner2f549082019-03-29 15:13:46 +01002409 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002410 status = config_init_env_warnoptions(config, &env_warnoptions);
2411 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002412 goto done;
2413 }
2414 }
2415
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002416 /* Handle early PySys_AddWarnOption() calls */
2417 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2418 if (_PyStatus_EXCEPTION(status)) {
2419 goto done;
2420 }
2421
Victor Stinner331a6a52019-05-27 16:39:22 +02002422 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002423 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002424 &env_warnoptions,
2425 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002426 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002427 goto done;
2428 }
2429
Victor Stinner331a6a52019-05-27 16:39:22 +02002430 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002431
2432done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002433 _PyWideStringList_Clear(&cmdline_warnoptions);
2434 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002435 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002436 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002437}
2438
2439
Victor Stinner331a6a52019-05-27 16:39:22 +02002440PyStatus
2441_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002442{
Victor Stinner331a6a52019-05-27 16:39:22 +02002443 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2444 if (_PyStatus_EXCEPTION(status)) {
2445 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002446 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002447
Victor Stinner5f38b842019-05-01 02:30:12 +02002448 return _PyArgv_AsWstrList(args, &config->argv);
2449}
2450
2451
Victor Stinner70005ac2019-05-02 15:25:34 -04002452/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2453 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002454PyStatus
2455PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002456{
2457 _PyArgv args = {
2458 .argc = argc,
2459 .use_bytes_argv = 1,
2460 .bytes_argv = argv,
2461 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002462 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002463}
2464
2465
Victor Stinner331a6a52019-05-27 16:39:22 +02002466PyStatus
2467PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002468{
2469 _PyArgv args = {
2470 .argc = argc,
2471 .use_bytes_argv = 0,
2472 .bytes_argv = NULL,
2473 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002474 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002475}
2476
2477
Victor Stinner36242fd2019-07-01 19:13:50 +02002478PyStatus
2479PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2480 Py_ssize_t length, wchar_t **items)
2481{
2482 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2483 if (_PyStatus_EXCEPTION(status)) {
2484 return status;
2485 }
2486
2487 PyWideStringList list2 = {.length = length, .items = items};
2488 if (_PyWideStringList_Copy(list, &list2) < 0) {
2489 return _PyStatus_NO_MEMORY();
2490 }
2491 return _PyStatus_OK();
2492}
2493
2494
Victor Stinner331a6a52019-05-27 16:39:22 +02002495/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002496
2497 * Command line arguments
2498 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002499 * Py_xxx global configuration variables
2500
2501 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002502PyStatus
2503PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002504{
Victor Stinner331a6a52019-05-27 16:39:22 +02002505 PyStatus status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002506
Victor Stinner331a6a52019-05-27 16:39:22 +02002507 status = _Py_PreInitializeFromConfig(config, NULL);
2508 if (_PyStatus_EXCEPTION(status)) {
2509 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002510 }
2511
Victor Stinner331a6a52019-05-27 16:39:22 +02002512 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002513
Victor Stinnerdedaac02020-06-08 18:44:50 +02002514 if (config->_orig_argv.length == 0
2515 && !(config->argv.length == 1
2516 && wcscmp(config->argv.items[0], L"") == 0))
2517 {
2518 if (_PyWideStringList_Copy(&config->_orig_argv, &config->argv) < 0) {
2519 return _PyStatus_NO_MEMORY();
2520 }
Victor Stinnercab5d072019-05-17 19:01:14 +02002521 }
2522
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002523 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002524 status = core_read_precmdline(config, &precmdline);
2525 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002526 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002527 }
2528
Victor Stinner870b0352019-05-17 03:15:12 +02002529 assert(config->isolated >= 0);
2530 if (config->isolated) {
2531 config->use_environment = 0;
2532 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002533 }
2534
Victor Stinner331a6a52019-05-27 16:39:22 +02002535 status = config_read_cmdline(config);
2536 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002537 goto done;
2538 }
2539
Victor Stinner120b7072019-08-23 18:03:08 +01002540 /* Handle early PySys_AddXOption() calls */
2541 status = _PySys_ReadPreinitXOptions(config);
2542 if (_PyStatus_EXCEPTION(status)) {
2543 goto done;
2544 }
2545
Victor Stinner331a6a52019-05-27 16:39:22 +02002546 status = config_read(config);
2547 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002548 goto done;
2549 }
2550
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002551 /* Check config consistency */
2552 assert(config->isolated >= 0);
2553 assert(config->use_environment >= 0);
2554 assert(config->dev_mode >= 0);
Victor Stinner1def7752020-04-23 03:03:24 +02002555 assert(config->_use_peg_parser >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002556 assert(config->install_signal_handlers >= 0);
2557 assert(config->use_hash_seed >= 0);
2558 assert(config->faulthandler >= 0);
2559 assert(config->tracemalloc >= 0);
2560 assert(config->site_import >= 0);
2561 assert(config->bytes_warning >= 0);
2562 assert(config->inspect >= 0);
2563 assert(config->interactive >= 0);
2564 assert(config->optimization_level >= 0);
2565 assert(config->parser_debug >= 0);
2566 assert(config->write_bytecode >= 0);
2567 assert(config->verbose >= 0);
2568 assert(config->quiet >= 0);
2569 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002570 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002571 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002572 assert(config->buffered_stdio >= 0);
2573 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002574 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002575 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2576 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002577 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2578 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2579 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002580 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002581 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002582 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002583 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002584 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002585 assert(config->prefix != NULL);
2586 assert(config->base_prefix != NULL);
2587 assert(config->exec_prefix != NULL);
2588 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002589 }
Victor Stinner81750642020-06-08 19:36:13 +02002590 assert(config->platlibdir != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002591 assert(config->filesystem_encoding != NULL);
2592 assert(config->filesystem_errors != NULL);
2593 assert(config->stdio_encoding != NULL);
2594 assert(config->stdio_errors != NULL);
2595#ifdef MS_WINDOWS
2596 assert(config->legacy_windows_stdio >= 0);
2597#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002598 /* -c and -m options are exclusive */
2599 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002600 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002601 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002602 assert(config->pathconfig_warnings >= 0);
Victor Stinnerdedaac02020-06-08 18:44:50 +02002603 assert(_PyWideStringList_CheckConsistency(&config->_orig_argv));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002604
Victor Stinner331a6a52019-05-27 16:39:22 +02002605 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002606
2607done:
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002608 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002609 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002610}
Victor Stinner1075d162019-03-25 23:19:57 +01002611
2612
2613PyObject*
2614_Py_GetConfigsAsDict(void)
2615{
Victor Stinner331a6a52019-05-27 16:39:22 +02002616 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002617 PyObject *dict = NULL;
2618
Victor Stinner331a6a52019-05-27 16:39:22 +02002619 result = PyDict_New();
2620 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002621 goto error;
2622 }
2623
Victor Stinner331a6a52019-05-27 16:39:22 +02002624 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002625 dict = _Py_GetGlobalVariablesAsDict();
2626 if (dict == NULL) {
2627 goto error;
2628 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002629 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002630 goto error;
2631 }
2632 Py_CLEAR(dict);
2633
2634 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002635 PyThreadState *tstate = _PyThreadState_GET();
2636 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002637 dict = _PyPreConfig_AsDict(pre_config);
2638 if (dict == NULL) {
2639 goto error;
2640 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002641 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002642 goto error;
2643 }
2644 Py_CLEAR(dict);
2645
2646 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002647 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinner331a6a52019-05-27 16:39:22 +02002648 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002649 if (dict == NULL) {
2650 goto error;
2651 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002652 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002653 goto error;
2654 }
2655 Py_CLEAR(dict);
2656
Victor Stinner331a6a52019-05-27 16:39:22 +02002657 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002658
2659error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002660 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002661 Py_XDECREF(dict);
2662 return NULL;
2663}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002664
2665
2666static void
2667init_dump_ascii_wstr(const wchar_t *str)
2668{
2669 if (str == NULL) {
2670 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002671 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002672 }
2673
2674 PySys_WriteStderr("'");
2675 for (; *str != L'\0'; str++) {
Miss Islington (bot)b2376f92020-09-09 03:31:25 -07002676 unsigned int ch = (unsigned int)*str;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002677 if (ch == L'\'') {
2678 PySys_WriteStderr("\\'");
2679 } else if (0x20 <= ch && ch < 0x7f) {
Miss Islington (bot)7aa534c2020-09-21 01:58:27 -07002680 PySys_WriteStderr("%c", ch);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002681 }
2682 else if (ch <= 0xff) {
2683 PySys_WriteStderr("\\x%02x", ch);
2684 }
2685#if SIZEOF_WCHAR_T > 2
2686 else if (ch > 0xffff) {
2687 PySys_WriteStderr("\\U%08x", ch);
2688 }
2689#endif
2690 else {
2691 PySys_WriteStderr("\\u%04x", ch);
2692 }
2693 }
2694 PySys_WriteStderr("'");
2695}
2696
2697
2698/* Dump the Python path configuration into sys.stderr */
2699void
2700_Py_DumpPathConfig(PyThreadState *tstate)
2701{
2702 PyObject *exc_type, *exc_value, *exc_tb;
2703 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2704
2705 PySys_WriteStderr("Python path configuration:\n");
2706
2707#define DUMP_CONFIG(NAME, FIELD) \
2708 do { \
2709 PySys_WriteStderr(" " NAME " = "); \
2710 init_dump_ascii_wstr(config->FIELD); \
2711 PySys_WriteStderr("\n"); \
2712 } while (0)
2713
Victor Stinnerda7933e2020-04-13 03:04:28 +02002714 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002715 DUMP_CONFIG("PYTHONHOME", home);
2716 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2717 DUMP_CONFIG("program name", program_name);
2718 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2719 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2720 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2721 PySys_WriteStderr(" import site = %i\n", config->site_import);
2722#undef DUMP_CONFIG
2723
2724#define DUMP_SYS(NAME) \
2725 do { \
2726 obj = PySys_GetObject(#NAME); \
2727 PySys_FormatStderr(" sys.%s = ", #NAME); \
2728 if (obj != NULL) { \
2729 PySys_FormatStderr("%A", obj); \
2730 } \
2731 else { \
2732 PySys_WriteStderr("(not set)"); \
2733 } \
2734 PySys_FormatStderr("\n"); \
2735 } while (0)
2736
2737 PyObject *obj;
2738 DUMP_SYS(_base_executable);
2739 DUMP_SYS(base_prefix);
2740 DUMP_SYS(base_exec_prefix);
Victor Stinner81750642020-06-08 19:36:13 +02002741 DUMP_SYS(platlibdir);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002742 DUMP_SYS(executable);
2743 DUMP_SYS(prefix);
2744 DUMP_SYS(exec_prefix);
2745#undef DUMP_SYS
2746
2747 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2748 if (sys_path != NULL && PyList_Check(sys_path)) {
2749 PySys_WriteStderr(" sys.path = [\n");
2750 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2751 for (Py_ssize_t i=0; i < len; i++) {
2752 PyObject *path = PyList_GET_ITEM(sys_path, i);
2753 PySys_FormatStderr(" %A,\n", path);
2754 }
2755 PySys_WriteStderr(" ]\n");
2756 }
2757
2758 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2759}