blob: d0ff888c7f778e8161ae336c0f17e2e248777291 [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 Stinner95e2cbf2019-03-01 16:25:19 +010014#if defined(MS_WINDOWS) || defined(__CYGWIN__)
Victor Stinner95e2cbf2019-03-01 16:25:19 +010015# ifdef HAVE_IO_H
16# include <io.h>
17# endif
18# ifdef HAVE_FCNTL_H
Victor Stinnere5014be2020-04-14 17:52:15 +020019# include <fcntl.h> // O_BINARY
Victor Stinner95e2cbf2019-03-01 16:25:19 +010020# endif
Victor Stinnerb2457ef2018-08-29 13:25:36 +020021#endif
22
Sandro Mani8f023a22020-06-08 17:28:11 +020023#ifndef PLATLIBDIR
24# error "PLATLIBDIR macro must be defined"
25#endif
26
Victor Stinner6c785c02018-08-01 17:56:14 +020027
Victor Stinner95e2cbf2019-03-01 16:25:19 +010028/* --- Command line options --------------------------------------- */
29
Victor Stinner95e2cbf2019-03-01 16:25:19 +010030/* Short usage message (with %s for argv0) */
31static const char usage_line[] =
32"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
33
34/* Long usage message, split into parts < 512 bytes */
35static const char usage_1[] = "\
36Options and arguments (and corresponding environment variables):\n\
37-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
38 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
39-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
40-c cmd : program passed in as string (terminates option list)\n\
41-d : debug output from parser; also PYTHONDEBUG=x\n\
42-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
43-h : print this help message and exit (also --help)\n\
44";
45static const char usage_2[] = "\
46-i : inspect interactively after running script; forces a prompt even\n\
47 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
48-I : isolate Python from the user's environment (implies -E and -s)\n\
49-m mod : run library module as a script (terminates option list)\n\
50-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
51 .pyc extension; also PYTHONOPTIMIZE=x\n\
52-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
53 .pyc extension\n\
54-q : don't print version and copyright messages on interactive startup\n\
55-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
56-S : don't imply 'import site' on initialization\n\
57";
58static const char usage_3[] = "\
59-u : force the stdout and stderr streams to be unbuffered;\n\
60 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
61-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
62 can be supplied multiple times to increase verbosity\n\
63-V : print the Python version number and exit (also --version)\n\
64 when given twice, print more information about the build\n\
65-W arg : warning control; arg is action:message:category:module:lineno\n\
66 also PYTHONWARNINGS=arg\n\
67-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000068-X opt : set implementation-specific option. The following options are available:\n\
69\n\
70 -X faulthandler: enable faulthandler\n\
71 -X showrefcount: output the total reference count and number of used\n\
72 memory blocks when the program finishes or after each statement in the\n\
73 interactive interpreter. This only works on debug builds\n\
74 -X tracemalloc: start tracing Python memory allocations using the\n\
75 tracemalloc module. By default, only the most recent frame is stored in a\n\
76 traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\
77 traceback limit of NFRAME frames\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000078 -X importtime: show how long each import takes. It shows module name,\n\
79 cumulative time (including nested imports) and self time (excluding\n\
80 nested imports). Note that its output may be broken in multi-threaded\n\
81 application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
Serhiy Storchaka58de1dd2020-09-09 03:28:02 +030082 -X dev: enable CPython's \"development mode\", introducing additional runtime\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000083 checks which are too expensive to be enabled by default. Effect of the\n\
84 developer mode:\n\
85 * Add default warning filter, as -W default\n\
86 * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\
87 * Enable the faulthandler module to dump the Python traceback on a crash\n\
88 * Enable asyncio debug mode\n\
89 * Set the dev_mode attribute of sys.flags to True\n\
90 * io.IOBase destructor logs close() exceptions\n\
91 -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\
92 locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\
93 otherwise activate automatically)\n\
94 -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
95 given directory instead of to the code tree\n\
96\n\
Victor Stinner95e2cbf2019-03-01 16:25:19 +010097--check-hash-based-pycs always|default|never:\n\
98 control how Python invalidates hash-based .pyc files\n\
99";
100static const char usage_4[] = "\
101file : program read from script file\n\
102- : program read from stdin (default; interactive mode if a tty)\n\
103arg ...: arguments passed to program in sys.argv[1:]\n\n\
104Other environment variables:\n\
105PYTHONSTARTUP: file executed on interactive startup (no default)\n\
106PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
107 default module search path. The result is sys.path.\n\
108";
109static const char usage_5[] =
110"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
111" The default module search path uses %s.\n"
Sandro Mani8f023a22020-06-08 17:28:11 +0200112"PYTHONPLATLIBDIR : override sys.platlibdir.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100113"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
Inada Naoki95826c72019-12-14 14:27:32 +0900114"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100115"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
116"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
117static const char usage_6[] =
118"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Serhiy Storchakae9c90aa2019-08-24 12:49:27 +0300119" to seed the hashes of str and bytes objects. It can also be set to an\n"
120" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100121" predictable seed.\n"
122"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
123" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
124" hooks.\n"
125"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
126" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
127" locale coercion and locale compatibility warnings on stderr.\n"
128"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
129" debugger. It can be set to the callable of your debugger of choice.\n"
130"PYTHONDEVMODE: enable the development mode.\n"
131"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
132
133#if defined(MS_WINDOWS)
134# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
135#else
136# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
137#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200138
139
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100140/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200141
Victor Stinner6c785c02018-08-01 17:56:14 +0200142/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200143 stdin and stdout error handler to "surrogateescape". */
144int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200145int Py_DebugFlag = 0; /* Needed by parser.c */
146int Py_VerboseFlag = 0; /* Needed by import.c */
147int Py_QuietFlag = 0; /* Needed by sysmodule.c */
148int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
149int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
150int Py_OptimizeFlag = 0; /* Needed by compile.c */
151int Py_NoSiteFlag = 0; /* Suppress 'import site' */
152int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
153int Py_FrozenFlag = 0; /* Needed by getpath.c */
154int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
155int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
156int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
157int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
158int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
159int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
160#ifdef MS_WINDOWS
161int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
162int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
163#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200164
165
Victor Stinner1075d162019-03-25 23:19:57 +0100166static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100167_Py_GetGlobalVariablesAsDict(void)
168{
169 PyObject *dict, *obj;
170
171 dict = PyDict_New();
172 if (dict == NULL) {
173 return NULL;
174 }
175
176#define SET_ITEM(KEY, EXPR) \
177 do { \
178 obj = (EXPR); \
179 if (obj == NULL) { \
180 return NULL; \
181 } \
182 int res = PyDict_SetItemString(dict, (KEY), obj); \
183 Py_DECREF(obj); \
184 if (res < 0) { \
185 goto fail; \
186 } \
187 } while (0)
188#define SET_ITEM_INT(VAR) \
189 SET_ITEM(#VAR, PyLong_FromLong(VAR))
190#define FROM_STRING(STR) \
191 ((STR != NULL) ? \
192 PyUnicode_FromString(STR) \
193 : (Py_INCREF(Py_None), Py_None))
194#define SET_ITEM_STR(VAR) \
195 SET_ITEM(#VAR, FROM_STRING(VAR))
196
197 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
198 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
199 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
200 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
201
202 SET_ITEM_INT(Py_UTF8Mode);
203 SET_ITEM_INT(Py_DebugFlag);
204 SET_ITEM_INT(Py_VerboseFlag);
205 SET_ITEM_INT(Py_QuietFlag);
206 SET_ITEM_INT(Py_InteractiveFlag);
207 SET_ITEM_INT(Py_InspectFlag);
208
209 SET_ITEM_INT(Py_OptimizeFlag);
210 SET_ITEM_INT(Py_NoSiteFlag);
211 SET_ITEM_INT(Py_BytesWarningFlag);
212 SET_ITEM_INT(Py_FrozenFlag);
213 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
214 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
215 SET_ITEM_INT(Py_NoUserSiteDirectory);
216 SET_ITEM_INT(Py_UnbufferedStdioFlag);
217 SET_ITEM_INT(Py_HashRandomizationFlag);
218 SET_ITEM_INT(Py_IsolatedFlag);
219
220#ifdef MS_WINDOWS
221 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
222 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
223#endif
224
225 return dict;
226
227fail:
228 Py_DECREF(dict);
229 return NULL;
230
231#undef FROM_STRING
232#undef SET_ITEM
233#undef SET_ITEM_INT
234#undef SET_ITEM_STR
235}
236
237
Victor Stinner331a6a52019-05-27 16:39:22 +0200238/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200239
Victor Stinner331a6a52019-05-27 16:39:22 +0200240PyStatus PyStatus_Ok(void)
241{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200242
Victor Stinner331a6a52019-05-27 16:39:22 +0200243PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200244{
Victor Stinner331a6a52019-05-27 16:39:22 +0200245 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner871ff772019-05-17 23:54:00 +0200246 .err_msg = err_msg};
247}
248
Victor Stinner331a6a52019-05-27 16:39:22 +0200249PyStatus PyStatus_NoMemory(void)
250{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200251
Victor Stinner331a6a52019-05-27 16:39:22 +0200252PyStatus PyStatus_Exit(int exitcode)
253{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200254
255
Victor Stinner331a6a52019-05-27 16:39:22 +0200256int PyStatus_IsError(PyStatus status)
257{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200258
Victor Stinner331a6a52019-05-27 16:39:22 +0200259int PyStatus_IsExit(PyStatus status)
260{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200261
Victor Stinner331a6a52019-05-27 16:39:22 +0200262int PyStatus_Exception(PyStatus status)
263{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200264
265
Victor Stinner331a6a52019-05-27 16:39:22 +0200266/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100267
268#ifndef NDEBUG
269int
Victor Stinner331a6a52019-05-27 16:39:22 +0200270_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100271{
272 assert(list->length >= 0);
273 if (list->length != 0) {
274 assert(list->items != NULL);
275 }
276 for (Py_ssize_t i = 0; i < list->length; i++) {
277 assert(list->items[i] != NULL);
278 }
279 return 1;
280}
281#endif /* Py_DEBUG */
282
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100283
Victor Stinner6c785c02018-08-01 17:56:14 +0200284void
Victor Stinner331a6a52019-05-27 16:39:22 +0200285_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200286{
Victor Stinner331a6a52019-05-27 16:39:22 +0200287 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100288 for (Py_ssize_t i=0; i < list->length; i++) {
289 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200290 }
Victor Stinner74f65682019-03-15 15:08:05 +0100291 PyMem_RawFree(list->items);
292 list->length = 0;
293 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200294}
295
296
Victor Stinner74f65682019-03-15 15:08:05 +0100297int
Victor Stinner331a6a52019-05-27 16:39:22 +0200298_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200299{
Victor Stinner331a6a52019-05-27 16:39:22 +0200300 assert(_PyWideStringList_CheckConsistency(list));
301 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100302
303 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200304 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100305 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300306 }
Victor Stinner74f65682019-03-15 15:08:05 +0100307
Victor Stinnerfb4ae152019-09-30 01:40:17 +0200308 PyWideStringList copy = _PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100309
310 size_t size = list2->length * sizeof(list2->items[0]);
311 copy.items = PyMem_RawMalloc(size);
312 if (copy.items == NULL) {
313 return -1;
314 }
315
316 for (Py_ssize_t i=0; i < list2->length; i++) {
317 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
318 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200319 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100320 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200321 }
Victor Stinner74f65682019-03-15 15:08:05 +0100322 copy.items[i] = item;
323 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200324 }
Victor Stinner74f65682019-03-15 15:08:05 +0100325
Victor Stinner331a6a52019-05-27 16:39:22 +0200326 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100327 *list = copy;
328 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200329}
330
331
Victor Stinner331a6a52019-05-27 16:39:22 +0200332PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100333PyWideStringList_Insert(PyWideStringList *list,
334 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100335{
Victor Stinner3842f292019-08-23 16:57:54 +0100336 Py_ssize_t len = list->length;
337 if (len == PY_SSIZE_T_MAX) {
Min ho Kim96e12d52019-07-22 06:12:33 +1000338 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200339 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100340 }
Victor Stinner3842f292019-08-23 16:57:54 +0100341 if (index < 0) {
342 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
343 }
344 if (index > len) {
345 index = len;
346 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100347
Victor Stinner74f65682019-03-15 15:08:05 +0100348 wchar_t *item2 = _PyMem_RawWcsdup(item);
349 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200350 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100351 }
Victor Stinner74f65682019-03-15 15:08:05 +0100352
Victor Stinner3842f292019-08-23 16:57:54 +0100353 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100354 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
355 if (items2 == NULL) {
356 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200357 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100358 }
359
Victor Stinner3842f292019-08-23 16:57:54 +0100360 if (index < len) {
361 memmove(&items2[index + 1],
362 &items2[index],
363 (len - index) * sizeof(items2[0]));
364 }
365
366 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100367 list->items = items2;
368 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200369 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100370}
371
372
Victor Stinner331a6a52019-05-27 16:39:22 +0200373PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100374PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
375{
376 return PyWideStringList_Insert(list, list->length, item);
377}
378
379
380PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200381_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100382{
383 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200384 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
385 if (_PyStatus_EXCEPTION(status)) {
386 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100387 }
388 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200389 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100390}
391
392
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100393static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200394_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100395{
396 for (Py_ssize_t i = 0; i < list->length; i++) {
397 if (wcscmp(list->items[i], item) == 0) {
398 return 1;
399 }
400 }
401 return 0;
402}
403
404
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100405PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200406_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100407{
Victor Stinner331a6a52019-05-27 16:39:22 +0200408 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100409
Victor Stinner74f65682019-03-15 15:08:05 +0100410 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100411 if (pylist == NULL) {
412 return NULL;
413 }
414
Victor Stinner74f65682019-03-15 15:08:05 +0100415 for (Py_ssize_t i = 0; i < list->length; i++) {
416 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
417 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100418 Py_DECREF(pylist);
419 return NULL;
420 }
Victor Stinner74f65682019-03-15 15:08:05 +0100421 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100422 }
423 return pylist;
424}
425
426
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100427/* --- Py_SetStandardStreamEncoding() ----------------------------- */
428
Victor Stinner124b9eb2018-08-29 01:29:06 +0200429/* Helper to allow an embedding application to override the normal
430 * mechanism that attempts to figure out an appropriate IO encoding
431 */
432
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200433static char *_Py_StandardStreamEncoding = NULL;
434static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200435
436int
437Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
438{
439 if (Py_IsInitialized()) {
440 /* This is too late to have any effect */
441 return -1;
442 }
443
444 int res = 0;
445
446 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
447 but Py_Initialize() can change the allocator. Use a known allocator
448 to be able to release the memory later. */
449 PyMemAllocatorEx old_alloc;
450 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
451
452 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
453 * initialised yet.
454 *
455 * However, the raw memory allocators are initialised appropriately
456 * as C static variables, so _PyMem_RawStrdup is OK even though
457 * Py_Initialize hasn't been called yet.
458 */
459 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200460 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200461 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
462 if (!_Py_StandardStreamEncoding) {
463 res = -2;
464 goto done;
465 }
466 }
467 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200468 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200469 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
470 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200471 PyMem_RawFree(_Py_StandardStreamEncoding);
472 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200473 res = -3;
474 goto done;
475 }
476 }
477#ifdef MS_WINDOWS
478 if (_Py_StandardStreamEncoding) {
479 /* Overriding the stream encoding implies legacy streams */
480 Py_LegacyWindowsStdioFlag = 1;
481 }
482#endif
483
484done:
485 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
486
487 return res;
488}
489
490
491void
492_Py_ClearStandardStreamEncoding(void)
493{
494 /* Use the same allocator than Py_SetStandardStreamEncoding() */
495 PyMemAllocatorEx old_alloc;
496 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
497
498 /* We won't need them anymore. */
499 if (_Py_StandardStreamEncoding) {
500 PyMem_RawFree(_Py_StandardStreamEncoding);
501 _Py_StandardStreamEncoding = NULL;
502 }
503 if (_Py_StandardStreamErrors) {
504 PyMem_RawFree(_Py_StandardStreamErrors);
505 _Py_StandardStreamErrors = NULL;
506 }
507
508 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
509}
510
511
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100512/* --- Py_GetArgcArgv() ------------------------------------------- */
513
514/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200515static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100516
517
518void
519_Py_ClearArgcArgv(void)
520{
521 PyMemAllocatorEx old_alloc;
522 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
523
Victor Stinner331a6a52019-05-27 16:39:22 +0200524 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100525
526 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
527}
528
529
Victor Stinner4fffd382019-03-06 01:44:31 +0100530static int
Victor Stinner74f65682019-03-15 15:08:05 +0100531_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100532{
Victor Stinner331a6a52019-05-27 16:39:22 +0200533 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100534 int res;
535
536 PyMemAllocatorEx old_alloc;
537 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
538
Victor Stinner331a6a52019-05-27 16:39:22 +0200539 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100540
541 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
542 return res;
543}
544
545
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100546void
547Py_GetArgcArgv(int *argc, wchar_t ***argv)
548{
Victor Stinner74f65682019-03-15 15:08:05 +0100549 *argc = (int)orig_argv.length;
550 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100551}
552
553
Victor Stinner331a6a52019-05-27 16:39:22 +0200554/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100555
556#define DECODE_LOCALE_ERR(NAME, LEN) \
557 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200558 ? _PyStatus_ERR("cannot decode " NAME) \
559 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100560
Victor Stinner441b10c2019-09-28 04:28:35 +0200561
Victor Stinner6c785c02018-08-01 17:56:14 +0200562/* Free memory allocated in config, but don't clear all attributes */
563void
Victor Stinner331a6a52019-05-27 16:39:22 +0200564PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200565{
566#define CLEAR(ATTR) \
567 do { \
568 PyMem_RawFree(ATTR); \
569 ATTR = NULL; \
570 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200571
572 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200573 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200574 CLEAR(config->home);
575 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200576
Victor Stinner331a6a52019-05-27 16:39:22 +0200577 _PyWideStringList_Clear(&config->argv);
578 _PyWideStringList_Clear(&config->warnoptions);
579 _PyWideStringList_Clear(&config->xoptions);
580 _PyWideStringList_Clear(&config->module_search_paths);
581 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200582
583 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700584 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200585 CLEAR(config->prefix);
586 CLEAR(config->base_prefix);
587 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200588 CLEAR(config->base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200589 CLEAR(config->platlibdir);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200590
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200591 CLEAR(config->filesystem_encoding);
592 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200593 CLEAR(config->stdio_encoding);
594 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100595 CLEAR(config->run_command);
596 CLEAR(config->run_module);
597 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400598 CLEAR(config->check_hash_pycs_mode);
Victor Stinnere2d47a02020-06-15 16:27:47 +0200599
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200600 _PyWideStringList_Clear(&config->orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200601#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200602}
603
604
Victor Stinner8462a492019-10-01 12:06:16 +0200605void
Victor Stinner331a6a52019-05-27 16:39:22 +0200606_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200607{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200608 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200609
Victor Stinner022be022019-05-22 23:58:50 +0200610 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200611 config->isolated = -1;
612 config->use_environment = -1;
613 config->dev_mode = -1;
614 config->install_signal_handlers = 1;
615 config->use_hash_seed = -1;
616 config->faulthandler = -1;
617 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200618 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200619 config->parse_argv = 0;
620 config->site_import = -1;
621 config->bytes_warning = -1;
622 config->inspect = -1;
623 config->interactive = -1;
624 config->optimization_level = -1;
625 config->parser_debug= -1;
626 config->write_bytecode = -1;
627 config->verbose = -1;
628 config->quiet = -1;
629 config->user_site_directory = -1;
630 config->configure_c_stdio = 0;
631 config->buffered_stdio = -1;
632 config->_install_importlib = 1;
633 config->check_hash_pycs_mode = NULL;
634 config->pathconfig_warnings = -1;
635 config->_init_main = 1;
Victor Stinner252346a2020-05-01 11:33:44 +0200636 config->_isolated_interpreter = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200637#ifdef MS_WINDOWS
638 config->legacy_windows_stdio = -1;
639#endif
640}
641
642
Victor Stinner8462a492019-10-01 12:06:16 +0200643static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200644config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200645{
Victor Stinner8462a492019-10-01 12:06:16 +0200646 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200647
648 config->isolated = 0;
649 config->use_environment = 1;
650 config->site_import = 1;
651 config->bytes_warning = 0;
652 config->inspect = 0;
653 config->interactive = 0;
654 config->optimization_level = 0;
655 config->parser_debug= 0;
656 config->write_bytecode = 1;
657 config->verbose = 0;
658 config->quiet = 0;
659 config->user_site_directory = 1;
660 config->buffered_stdio = 1;
661 config->pathconfig_warnings = 1;
662#ifdef MS_WINDOWS
663 config->legacy_windows_stdio = 0;
664#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200665}
666
667
Victor Stinner8462a492019-10-01 12:06:16 +0200668void
Victor Stinner331a6a52019-05-27 16:39:22 +0200669PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200670{
Victor Stinner8462a492019-10-01 12:06:16 +0200671 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200672
Victor Stinner022be022019-05-22 23:58:50 +0200673 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200674 config->configure_c_stdio = 1;
675 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200676}
677
678
Victor Stinner8462a492019-10-01 12:06:16 +0200679void
Victor Stinner331a6a52019-05-27 16:39:22 +0200680PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200681{
Victor Stinner8462a492019-10-01 12:06:16 +0200682 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200683
Victor Stinner022be022019-05-22 23:58:50 +0200684 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200685 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200686 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200687 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200688 config->dev_mode = 0;
689 config->install_signal_handlers = 0;
690 config->use_hash_seed = 0;
691 config->faulthandler = 0;
692 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200693 config->pathconfig_warnings = 0;
694#ifdef MS_WINDOWS
695 config->legacy_windows_stdio = 0;
696#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200697}
698
699
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200700/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200701PyStatus
702PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200703{
Victor Stinner331a6a52019-05-27 16:39:22 +0200704 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
705 if (_PyStatus_EXCEPTION(status)) {
706 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200707 }
708
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200709 wchar_t *str2;
710 if (str != NULL) {
711 str2 = _PyMem_RawWcsdup(str);
712 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200713 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200714 }
715 }
716 else {
717 str2 = NULL;
718 }
719 PyMem_RawFree(*config_str);
720 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200721 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200722}
723
724
Victor Stinner331a6a52019-05-27 16:39:22 +0200725static PyStatus
726config_set_bytes_string(PyConfig *config, wchar_t **config_str,
727 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200728{
Victor Stinner331a6a52019-05-27 16:39:22 +0200729 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
730 if (_PyStatus_EXCEPTION(status)) {
731 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400732 }
733
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200734 wchar_t *str2;
735 if (str != NULL) {
736 size_t len;
737 str2 = Py_DecodeLocale(str, &len);
738 if (str2 == NULL) {
739 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200740 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200741 }
742 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200743 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200744 }
745 }
746 }
747 else {
748 str2 = NULL;
749 }
750 PyMem_RawFree(*config_str);
751 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200752 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200753}
754
755
Victor Stinner331a6a52019-05-27 16:39:22 +0200756#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
757 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400758
759
Victor Stinner70005ac2019-05-02 15:25:34 -0400760/* Decode str using Py_DecodeLocale() and set the result into *config_str.
761 Pre-initialize Python if needed to ensure that encodings are properly
762 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200763PyStatus
764PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner710e8262020-10-31 01:02:09 +0100765 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400766{
Victor Stinner331a6a52019-05-27 16:39:22 +0200767 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400768}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200769
770
Victor Stinner331a6a52019-05-27 16:39:22 +0200771PyStatus
772_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200773{
Victor Stinner331a6a52019-05-27 16:39:22 +0200774 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200775
Victor Stinner331a6a52019-05-27 16:39:22 +0200776 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200777
778#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200779#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200780 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200781 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
782 if (_PyStatus_EXCEPTION(status)) { \
783 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200784 } \
785 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100786#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200787 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200788 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200789 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200790 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200791 } while (0)
792
Victor Stinner6d1c4672019-05-20 11:02:00 +0200793 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100794 COPY_ATTR(isolated);
795 COPY_ATTR(use_environment);
796 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200797 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200798 COPY_ATTR(use_hash_seed);
799 COPY_ATTR(hash_seed);
800 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200801 COPY_ATTR(faulthandler);
802 COPY_ATTR(tracemalloc);
803 COPY_ATTR(import_time);
804 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200805 COPY_ATTR(dump_refs);
806 COPY_ATTR(malloc_stats);
807
Victor Stinner124b9eb2018-08-29 01:29:06 +0200808 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200809 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200810 COPY_WSTR_ATTR(home);
811 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200812
Victor Stinnerae239f62019-05-16 17:02:56 +0200813 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100814 COPY_WSTRLIST(argv);
815 COPY_WSTRLIST(warnoptions);
816 COPY_WSTRLIST(xoptions);
817 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200818 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200819
Victor Stinner124b9eb2018-08-29 01:29:06 +0200820 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700821 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200822 COPY_WSTR_ATTR(prefix);
823 COPY_WSTR_ATTR(base_prefix);
824 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200825 COPY_WSTR_ATTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200826 COPY_WSTR_ATTR(platlibdir);
Victor Stinner6c785c02018-08-01 17:56:14 +0200827
Victor Stinner6c785c02018-08-01 17:56:14 +0200828 COPY_ATTR(site_import);
829 COPY_ATTR(bytes_warning);
830 COPY_ATTR(inspect);
831 COPY_ATTR(interactive);
832 COPY_ATTR(optimization_level);
833 COPY_ATTR(parser_debug);
834 COPY_ATTR(write_bytecode);
835 COPY_ATTR(verbose);
836 COPY_ATTR(quiet);
837 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200838 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200839 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400840 COPY_WSTR_ATTR(filesystem_encoding);
841 COPY_WSTR_ATTR(filesystem_errors);
842 COPY_WSTR_ATTR(stdio_encoding);
843 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200844#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200845 COPY_ATTR(legacy_windows_stdio);
846#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100847 COPY_ATTR(skip_source_first_line);
848 COPY_WSTR_ATTR(run_command);
849 COPY_WSTR_ATTR(run_module);
850 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400851 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200852 COPY_ATTR(pathconfig_warnings);
853 COPY_ATTR(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200854 COPY_ATTR(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200855 COPY_WSTRLIST(orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200856
857#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200858#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200859#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200860 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200861}
862
863
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100864static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200865config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100866{
Victor Stinner8f427482020-07-08 00:20:37 +0200867 PyObject *dict = PyDict_New();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100868 if (dict == NULL) {
869 return NULL;
870 }
871
872#define SET_ITEM(KEY, EXPR) \
873 do { \
874 PyObject *obj = (EXPR); \
875 if (obj == NULL) { \
876 goto fail; \
877 } \
878 int res = PyDict_SetItemString(dict, (KEY), obj); \
879 Py_DECREF(obj); \
880 if (res < 0) { \
881 goto fail; \
882 } \
883 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100884#define SET_ITEM_INT(ATTR) \
885 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
886#define SET_ITEM_UINT(ATTR) \
887 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100888#define FROM_WSTRING(STR) \
889 ((STR != NULL) ? \
890 PyUnicode_FromWideChar(STR, -1) \
891 : (Py_INCREF(Py_None), Py_None))
892#define SET_ITEM_WSTR(ATTR) \
893 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
894#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200895 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100896
Victor Stinner6d1c4672019-05-20 11:02:00 +0200897 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100898 SET_ITEM_INT(isolated);
899 SET_ITEM_INT(use_environment);
900 SET_ITEM_INT(dev_mode);
901 SET_ITEM_INT(install_signal_handlers);
902 SET_ITEM_INT(use_hash_seed);
903 SET_ITEM_UINT(hash_seed);
904 SET_ITEM_INT(faulthandler);
905 SET_ITEM_INT(tracemalloc);
906 SET_ITEM_INT(import_time);
907 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100908 SET_ITEM_INT(dump_refs);
909 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400910 SET_ITEM_WSTR(filesystem_encoding);
911 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100912 SET_ITEM_WSTR(pycache_prefix);
913 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200914 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100915 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100916 SET_ITEM_WSTRLIST(xoptions);
917 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200918 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100919 SET_ITEM_WSTR(home);
920 SET_ITEM_WSTRLIST(module_search_paths);
921 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700922 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100923 SET_ITEM_WSTR(prefix);
924 SET_ITEM_WSTR(base_prefix);
925 SET_ITEM_WSTR(exec_prefix);
926 SET_ITEM_WSTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200927 SET_ITEM_WSTR(platlibdir);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100928 SET_ITEM_INT(site_import);
929 SET_ITEM_INT(bytes_warning);
930 SET_ITEM_INT(inspect);
931 SET_ITEM_INT(interactive);
932 SET_ITEM_INT(optimization_level);
933 SET_ITEM_INT(parser_debug);
934 SET_ITEM_INT(write_bytecode);
935 SET_ITEM_INT(verbose);
936 SET_ITEM_INT(quiet);
937 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200938 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100939 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400940 SET_ITEM_WSTR(stdio_encoding);
941 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100942#ifdef MS_WINDOWS
943 SET_ITEM_INT(legacy_windows_stdio);
944#endif
945 SET_ITEM_INT(skip_source_first_line);
946 SET_ITEM_WSTR(run_command);
947 SET_ITEM_WSTR(run_module);
948 SET_ITEM_WSTR(run_filename);
949 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400950 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200951 SET_ITEM_INT(pathconfig_warnings);
952 SET_ITEM_INT(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200953 SET_ITEM_INT(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200954 SET_ITEM_WSTRLIST(orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100955
956 return dict;
957
958fail:
959 Py_DECREF(dict);
960 return NULL;
961
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100962#undef FROM_WSTRING
963#undef SET_ITEM
964#undef SET_ITEM_INT
965#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100966#undef SET_ITEM_WSTR
967#undef SET_ITEM_WSTRLIST
968}
969
970
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100971static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200972config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200973{
Victor Stinner20004952019-03-26 02:31:11 +0100974 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200975}
976
977
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100978/* Get a copy of the environment variable as wchar_t*.
979 Return 0 on success, but *dest can be NULL.
980 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200981static PyStatus
982config_get_env_dup(PyConfig *config,
983 wchar_t **dest,
984 wchar_t *wname, char *name,
985 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200986{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200987 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100988 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200989
Victor Stinner20004952019-03-26 02:31:11 +0100990 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200991 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200992 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200993 }
994
995#ifdef MS_WINDOWS
996 const wchar_t *var = _wgetenv(wname);
997 if (!var || var[0] == '\0') {
998 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200999 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001000 }
1001
Victor Stinner331a6a52019-05-27 16:39:22 +02001002 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +02001003#else
1004 const char *var = getenv(name);
1005 if (!var || var[0] == '\0') {
1006 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001007 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001008 }
1009
Victor Stinner331a6a52019-05-27 16:39:22 +02001010 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001011#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001012}
1013
1014
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001015#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001016 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001017
1018
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001019static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001020config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001021{
Victor Stinner022be022019-05-22 23:58:50 +02001022 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1023 /* Python and Isolated configuration ignore global variables */
1024 return;
1025 }
1026
Victor Stinner6c785c02018-08-01 17:56:14 +02001027#define COPY_FLAG(ATTR, VALUE) \
1028 if (config->ATTR == -1) { \
1029 config->ATTR = VALUE; \
1030 }
1031#define COPY_NOT_FLAG(ATTR, VALUE) \
1032 if (config->ATTR == -1) { \
1033 config->ATTR = !(VALUE); \
1034 }
1035
Victor Stinner20004952019-03-26 02:31:11 +01001036 COPY_FLAG(isolated, Py_IsolatedFlag);
1037 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001038 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1039 COPY_FLAG(inspect, Py_InspectFlag);
1040 COPY_FLAG(interactive, Py_InteractiveFlag);
1041 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1042 COPY_FLAG(parser_debug, Py_DebugFlag);
1043 COPY_FLAG(verbose, Py_VerboseFlag);
1044 COPY_FLAG(quiet, Py_QuietFlag);
1045#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001046 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1047#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001048 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001049
Victor Stinner6c785c02018-08-01 17:56:14 +02001050 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1051 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1052 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1053 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1054
Victor Stinner6c785c02018-08-01 17:56:14 +02001055#undef COPY_FLAG
1056#undef COPY_NOT_FLAG
1057}
1058
1059
1060/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001061static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001062config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001063{
1064#define COPY_FLAG(ATTR, VAR) \
1065 if (config->ATTR != -1) { \
1066 VAR = config->ATTR; \
1067 }
1068#define COPY_NOT_FLAG(ATTR, VAR) \
1069 if (config->ATTR != -1) { \
1070 VAR = !config->ATTR; \
1071 }
1072
Victor Stinner20004952019-03-26 02:31:11 +01001073 COPY_FLAG(isolated, Py_IsolatedFlag);
1074 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001075 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1076 COPY_FLAG(inspect, Py_InspectFlag);
1077 COPY_FLAG(interactive, Py_InteractiveFlag);
1078 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1079 COPY_FLAG(parser_debug, Py_DebugFlag);
1080 COPY_FLAG(verbose, Py_VerboseFlag);
1081 COPY_FLAG(quiet, Py_QuietFlag);
1082#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001083 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1084#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001085 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001086
Victor Stinner6c785c02018-08-01 17:56:14 +02001087 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1088 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1089 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1090 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1091
Victor Stinner6c785c02018-08-01 17:56:14 +02001092 /* Random or non-zero hash seed */
1093 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1094 config->hash_seed != 0);
1095
1096#undef COPY_FLAG
1097#undef COPY_NOT_FLAG
1098}
1099
1100
1101/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1102 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001103static PyStatus
1104config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001105{
Victor Stinner331a6a52019-05-27 16:39:22 +02001106 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001107
Victor Stinner6c785c02018-08-01 17:56:14 +02001108 /* If Py_SetProgramName() was called, use its value */
1109 const wchar_t *program_name = _Py_path_config.program_name;
1110 if (program_name != NULL) {
1111 config->program_name = _PyMem_RawWcsdup(program_name);
1112 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001113 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001114 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001115 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001116 }
1117
1118#ifdef __APPLE__
1119 /* On MacOS X, when the Python interpreter is embedded in an
1120 application bundle, it gets executed by a bootstrapping script
1121 that does os.execve() with an argv[0] that's different from the
1122 actual Python executable. This is needed to keep the Finder happy,
1123 or rather, to work around Apple's overly strict requirements of
1124 the process name. However, we still need a usable sys.executable,
1125 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001126 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001127 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001128 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001129 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001130 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1131 "PYTHONEXECUTABLE environment variable");
1132 if (_PyStatus_EXCEPTION(status)) {
1133 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001134 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001135 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001136 }
1137#ifdef WITH_NEXT_FRAMEWORK
1138 else {
1139 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1140 if (pyvenv_launcher && *pyvenv_launcher) {
1141 /* Used by Mac/Tools/pythonw.c to forward
1142 * the argv0 of the stub executable
1143 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001144 status = CONFIG_SET_BYTES_STR(config,
1145 &config->program_name,
1146 pyvenv_launcher,
1147 "__PYVENV_LAUNCHER__ environment variable");
1148 if (_PyStatus_EXCEPTION(status)) {
1149 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001150 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001151
1152 /*
1153 * This environment variable is used to communicate between
1154 * the stub launcher and the real interpreter and isn't needed
1155 * beyond this point.
1156 *
1157 * Clean up to avoid problems when launching other programs
1158 * later on.
1159 */
1160 (void)unsetenv("__PYVENV_LAUNCHER__");
1161
Victor Stinner331a6a52019-05-27 16:39:22 +02001162 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001163 }
1164 }
1165#endif /* WITH_NEXT_FRAMEWORK */
1166#endif /* __APPLE__ */
1167
Victor Stinnerfed02e12019-05-17 11:12:09 +02001168 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001169 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001170 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1171 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1172 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001173 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001174 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001175 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001176 }
1177
Victor Stinnerfed02e12019-05-17 11:12:09 +02001178 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001179#ifdef MS_WINDOWS
1180 const wchar_t *default_program_name = L"python";
1181#else
1182 const wchar_t *default_program_name = L"python3";
1183#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001184 status = PyConfig_SetString(config, &config->program_name,
1185 default_program_name);
1186 if (_PyStatus_EXCEPTION(status)) {
1187 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001188 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001189 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001190}
1191
Victor Stinner331a6a52019-05-27 16:39:22 +02001192static PyStatus
1193config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001194{
1195 assert(config->executable == NULL);
1196
1197 /* If Py_SetProgramFullPath() was called, use its value */
1198 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1199 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001200 PyStatus status = PyConfig_SetString(config,
1201 &config->executable,
1202 program_full_path);
1203 if (_PyStatus_EXCEPTION(status)) {
1204 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001205 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001206 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001207 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001208 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001209}
Victor Stinner6c785c02018-08-01 17:56:14 +02001210
Victor Stinner4fffd382019-03-06 01:44:31 +01001211
Victor Stinner6c785c02018-08-01 17:56:14 +02001212static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001213config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001214{
Victor Stinner74f65682019-03-15 15:08:05 +01001215 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001216}
1217
1218
Victor Stinner331a6a52019-05-27 16:39:22 +02001219static PyStatus
1220config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001221{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001222 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001223
1224 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001225 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001226 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001227 PyStatus status = PyConfig_SetString(config, &config->home, home);
1228 if (_PyStatus_EXCEPTION(status)) {
1229 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001230 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001231 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001232 }
1233
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001234 return CONFIG_GET_ENV_DUP(config, &config->home,
1235 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001236}
1237
1238
Victor Stinner331a6a52019-05-27 16:39:22 +02001239static PyStatus
1240config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001241{
Victor Stinner331a6a52019-05-27 16:39:22 +02001242 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001243
1244 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1245 /* Convert a text seed to a numeric one */
1246 if (seed_text && strcmp(seed_text, "random") != 0) {
1247 const char *endptr = seed_text;
1248 unsigned long seed;
1249 errno = 0;
1250 seed = strtoul(seed_text, (char **)&endptr, 10);
1251 if (*endptr != '\0'
1252 || seed > 4294967295UL
1253 || (errno == ERANGE && seed == ULONG_MAX))
1254 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001255 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001256 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001257 }
1258 /* Use a specific hash */
1259 config->use_hash_seed = 1;
1260 config->hash_seed = seed;
1261 }
1262 else {
1263 /* Use a random hash */
1264 config->use_hash_seed = 0;
1265 config->hash_seed = 0;
1266 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001267 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001268}
1269
1270
Victor Stinner6c785c02018-08-01 17:56:14 +02001271static int
1272config_wstr_to_int(const wchar_t *wstr, int *result)
1273{
1274 const wchar_t *endptr = wstr;
1275 errno = 0;
1276 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1277 if (*endptr != '\0' || errno == ERANGE) {
1278 return -1;
1279 }
1280 if (value < INT_MIN || value > INT_MAX) {
1281 return -1;
1282 }
1283
1284 *result = (int)value;
1285 return 0;
1286}
1287
1288
Victor Stinner331a6a52019-05-27 16:39:22 +02001289static PyStatus
1290config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001291{
Victor Stinner331a6a52019-05-27 16:39:22 +02001292 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001293 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001294
Victor Stinner6c785c02018-08-01 17:56:14 +02001295 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001296 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1297 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1298 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1299 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001300
1301 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001302 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001303 if (dont_write_bytecode) {
1304 config->write_bytecode = 0;
1305 }
1306
1307 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001308 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001309 if (no_user_site_directory) {
1310 config->user_site_directory = 0;
1311 }
1312
1313 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001314 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001315 if (unbuffered_stdio) {
1316 config->buffered_stdio = 0;
1317 }
1318
1319#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001320 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinnere662c392020-11-01 23:07:23 +01001321 "PYTHONLEGACYWINDOWSSTDIO");
Victor Stinner6c785c02018-08-01 17:56:14 +02001322#endif
1323
Victor Stinner331a6a52019-05-27 16:39:22 +02001324 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001325 config->dump_refs = 1;
1326 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001327 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001328 config->malloc_stats = 1;
1329 }
1330
Victor Stinner331a6a52019-05-27 16:39:22 +02001331 if (config->pythonpath_env == NULL) {
1332 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1333 L"PYTHONPATH", "PYTHONPATH");
1334 if (_PyStatus_EXCEPTION(status)) {
1335 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001336 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001337 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001338
Sandro Mani8f023a22020-06-08 17:28:11 +02001339 if(config->platlibdir == NULL) {
1340 status = CONFIG_GET_ENV_DUP(config, &config->platlibdir,
1341 L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR");
1342 if (_PyStatus_EXCEPTION(status)) {
1343 return status;
1344 }
1345 }
1346
Victor Stinner6c785c02018-08-01 17:56:14 +02001347 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001348 status = config_init_hash_seed(config);
1349 if (_PyStatus_EXCEPTION(status)) {
1350 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001351 }
1352 }
1353
Victor Stinner331a6a52019-05-27 16:39:22 +02001354 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001355}
1356
1357
Victor Stinner331a6a52019-05-27 16:39:22 +02001358static PyStatus
1359config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001360{
1361 int nframe;
1362 int valid;
1363
Victor Stinner331a6a52019-05-27 16:39:22 +02001364 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001365 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001366 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001367 valid = (nframe >= 0);
1368 }
1369 else {
1370 valid = 0;
1371 }
1372 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001373 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001374 }
1375 config->tracemalloc = nframe;
1376 }
1377
1378 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1379 if (xoption) {
1380 const wchar_t *sep = wcschr(xoption, L'=');
1381 if (sep) {
1382 if (!config_wstr_to_int(sep + 1, &nframe)) {
1383 valid = (nframe >= 0);
1384 }
1385 else {
1386 valid = 0;
1387 }
1388 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001389 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1390 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001391 }
1392 }
1393 else {
1394 /* -X tracemalloc behaves as -X tracemalloc=1 */
1395 nframe = 1;
1396 }
1397 config->tracemalloc = nframe;
1398 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001399 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001400}
1401
1402
Victor Stinner331a6a52019-05-27 16:39:22 +02001403static PyStatus
1404config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001405{
1406 assert(config->pycache_prefix == NULL);
1407
1408 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1409 if (xoption) {
1410 const wchar_t *sep = wcschr(xoption, L'=');
1411 if (sep && wcslen(sep) > 1) {
1412 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1413 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001414 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001415 }
1416 }
1417 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001418 // PYTHONPYCACHEPREFIX env var ignored
1419 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001420 config->pycache_prefix = NULL;
1421 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001422 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001423 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001424
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001425 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1426 L"PYTHONPYCACHEPREFIX",
1427 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001428}
1429
1430
Victor Stinner331a6a52019-05-27 16:39:22 +02001431static PyStatus
1432config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001433{
1434 /* More complex options configured by env var and -X option */
1435 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001436 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001437 || config_get_xoption(config, L"faulthandler")) {
1438 config->faulthandler = 1;
1439 }
1440 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001441 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001442 || config_get_xoption(config, L"importtime")) {
1443 config->import_time = 1;
1444 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001445
Victor Stinner331a6a52019-05-27 16:39:22 +02001446 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001447 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001448 status = config_init_tracemalloc(config);
1449 if (_PyStatus_EXCEPTION(status)) {
1450 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001451 }
1452 }
1453
1454 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001455 status = config_init_pycache_prefix(config);
1456 if (_PyStatus_EXCEPTION(status)) {
1457 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001458 }
1459 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001460 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001461}
1462
1463
Victor Stinner709d23d2019-05-02 14:56:30 -04001464static const wchar_t *
Victor Stinner710e8262020-10-31 01:02:09 +01001465config_get_stdio_errors(const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001466{
Victor Stinner710e8262020-10-31 01:02:09 +01001467 if (preconfig->utf8_mode) {
1468 /* UTF-8 Mode uses UTF-8/surrogateescape */
1469 return L"surrogateescape";
1470 }
1471
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001472#ifndef MS_WINDOWS
1473 const char *loc = setlocale(LC_CTYPE, NULL);
1474 if (loc != NULL) {
1475 /* surrogateescape is the default in the legacy C and POSIX locales */
1476 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001477 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001478 }
1479
1480#ifdef PY_COERCE_C_LOCALE
1481 /* surrogateescape is the default in locale coercion target locales */
1482 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001483 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001484 }
1485#endif
1486 }
1487
Victor Stinner709d23d2019-05-02 14:56:30 -04001488 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001489#else
1490 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001491 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001492#endif
1493}
1494
1495
Victor Stinner82458b62020-11-01 20:59:35 +01001496// See also config_get_fs_encoding()
Victor Stinner331a6a52019-05-27 16:39:22 +02001497static PyStatus
Victor Stinner710e8262020-10-31 01:02:09 +01001498config_get_locale_encoding(PyConfig *config, const PyPreConfig *preconfig,
1499 wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001500{
Victor Stinnere662c392020-11-01 23:07:23 +01001501 wchar_t *encoding = _Py_GetLocaleEncoding();
Victor Stinner82458b62020-11-01 20:59:35 +01001502 if (encoding == NULL) {
Victor Stinnere662c392020-11-01 23:07:23 +01001503 return _PyStatus_NO_MEMORY();
Victor Stinner710e8262020-10-31 01:02:09 +01001504 }
Victor Stinner82458b62020-11-01 20:59:35 +01001505 PyStatus status = PyConfig_SetString(config, locale_encoding, encoding);
1506 PyMem_RawFree(encoding);
1507 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001508}
1509
1510
Victor Stinner331a6a52019-05-27 16:39:22 +02001511static PyStatus
1512config_init_stdio_encoding(PyConfig *config,
1513 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001514{
Victor Stinner331a6a52019-05-27 16:39:22 +02001515 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001516
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001517 /* If Py_SetStandardStreamEncoding() have been called, use these
1518 parameters. */
1519 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001520 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1521 _Py_StandardStreamEncoding,
1522 "_Py_StandardStreamEncoding");
1523 if (_PyStatus_EXCEPTION(status)) {
1524 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001525 }
1526 }
1527
1528 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001529 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1530 _Py_StandardStreamErrors,
1531 "_Py_StandardStreamErrors");
1532 if (_PyStatus_EXCEPTION(status)) {
1533 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001534 }
1535 }
1536
1537 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001538 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001539 }
1540
1541 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001542 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001543 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001544 char *pythonioencoding = _PyMem_RawStrdup(opt);
1545 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001546 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001547 }
1548
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001549 char *errors = strchr(pythonioencoding, ':');
1550 if (errors) {
1551 *errors = '\0';
1552 errors++;
1553 if (!errors[0]) {
1554 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001555 }
1556 }
1557
1558 /* Does PYTHONIOENCODING contain an encoding? */
1559 if (pythonioencoding[0]) {
1560 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001561 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1562 pythonioencoding,
1563 "PYTHONIOENCODING environment variable");
1564 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001565 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001566 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001567 }
1568 }
1569
1570 /* If the encoding is set but not the error handler,
1571 use "strict" error handler by default.
1572 PYTHONIOENCODING=latin1 behaves as
1573 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001574 if (!errors) {
1575 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001576 }
1577 }
1578
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001579 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001580 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1581 errors,
1582 "PYTHONIOENCODING environment variable");
1583 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001584 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001585 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001586 }
1587 }
1588
1589 PyMem_RawFree(pythonioencoding);
1590 }
1591
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001592 /* Choose the default error handler based on the current locale. */
1593 if (config->stdio_encoding == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001594 status = config_get_locale_encoding(config, preconfig,
1595 &config->stdio_encoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001596 if (_PyStatus_EXCEPTION(status)) {
1597 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001598 }
1599 }
1600 if (config->stdio_errors == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001601 const wchar_t *errors = config_get_stdio_errors(preconfig);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001602 assert(errors != NULL);
1603
Victor Stinner331a6a52019-05-27 16:39:22 +02001604 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1605 if (_PyStatus_EXCEPTION(status)) {
1606 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001607 }
1608 }
1609
Victor Stinner331a6a52019-05-27 16:39:22 +02001610 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001611}
1612
1613
Victor Stinner710e8262020-10-31 01:02:09 +01001614// See also config_get_locale_encoding()
1615static PyStatus
1616config_get_fs_encoding(PyConfig *config, const PyPreConfig *preconfig,
1617 wchar_t **fs_encoding)
1618{
1619#ifdef _Py_FORCE_UTF8_FS_ENCODING
1620 return PyConfig_SetString(config, fs_encoding, L"utf-8");
1621#elif defined(MS_WINDOWS)
1622 const wchar_t *encoding;
1623 if (preconfig->legacy_windows_fs_encoding) {
1624 // Legacy Windows filesystem encoding: mbcs/replace
1625 encoding = L"mbcs";
1626 }
1627 else {
1628 // Windows defaults to utf-8/surrogatepass (PEP 529)
1629 encoding = L"utf-8";
1630 }
1631 return PyConfig_SetString(config, fs_encoding, encoding);
1632#else // !MS_WINDOWS
1633 if (preconfig->utf8_mode) {
1634 return PyConfig_SetString(config, fs_encoding, L"utf-8");
1635 }
1636 else if (_Py_GetForceASCII()) {
1637 return PyConfig_SetString(config, fs_encoding, L"ascii");
1638 }
1639 else {
1640 return config_get_locale_encoding(config, preconfig, fs_encoding);
1641 }
1642#endif // !MS_WINDOWS
1643}
1644
1645
Victor Stinner331a6a52019-05-27 16:39:22 +02001646static PyStatus
1647config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001648{
Victor Stinner331a6a52019-05-27 16:39:22 +02001649 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001650
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001651 if (config->filesystem_encoding == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001652 status = config_get_fs_encoding(config, preconfig,
1653 &config->filesystem_encoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001654 if (_PyStatus_EXCEPTION(status)) {
1655 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001656 }
1657 }
1658
1659 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001660 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001661#ifdef MS_WINDOWS
1662 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001663 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001664 }
1665 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001666 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001667 }
1668#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001669 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001670#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001671 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1672 if (_PyStatus_EXCEPTION(status)) {
1673 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001674 }
1675 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001676 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001677}
1678
1679
Victor Stinner331a6a52019-05-27 16:39:22 +02001680static PyStatus
1681config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001682{
Victor Stinner331a6a52019-05-27 16:39:22 +02001683 PyStatus status;
1684 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001685
Victor Stinner20004952019-03-26 02:31:11 +01001686 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001687 status = config_read_env_vars(config);
1688 if (_PyStatus_EXCEPTION(status)) {
1689 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001690 }
1691 }
1692
1693 /* -X options */
1694 if (config_get_xoption(config, L"showrefcount")) {
1695 config->show_ref_count = 1;
1696 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001697
Victor Stinner331a6a52019-05-27 16:39:22 +02001698 status = config_read_complex_options(config);
1699 if (_PyStatus_EXCEPTION(status)) {
1700 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001701 }
1702
Victor Stinner6c785c02018-08-01 17:56:14 +02001703 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001704 status = config_init_home(config);
1705 if (_PyStatus_EXCEPTION(status)) {
1706 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001707 }
1708 }
1709
Steve Dower177a41a2018-11-17 20:41:48 -08001710 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001711 status = config_init_executable(config);
1712 if (_PyStatus_EXCEPTION(status)) {
1713 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001714 }
1715 }
1716
Sandro Mani8f023a22020-06-08 17:28:11 +02001717 if(config->platlibdir == NULL) {
1718 status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR,
1719 "PLATLIBDIR macro");
1720 if (_PyStatus_EXCEPTION(status)) {
1721 return status;
1722 }
1723 }
1724
Victor Stinner6c785c02018-08-01 17:56:14 +02001725 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001726 status = _PyConfig_InitPathConfig(config);
1727 if (_PyStatus_EXCEPTION(status)) {
1728 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001729 }
1730 }
1731
1732 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001733 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001734 if (config->faulthandler < 0) {
1735 config->faulthandler = 1;
1736 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001737 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001738 if (config->faulthandler < 0) {
1739 config->faulthandler = 0;
1740 }
1741 if (config->tracemalloc < 0) {
1742 config->tracemalloc = 0;
1743 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001744 if (config->use_hash_seed < 0) {
1745 config->use_hash_seed = 0;
1746 config->hash_seed = 0;
1747 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001748
Victor Stinner70fead22018-08-29 13:45:34 +02001749 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001750 status = config_init_fs_encoding(config, preconfig);
1751 if (_PyStatus_EXCEPTION(status)) {
1752 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001753 }
1754 }
1755
Victor Stinner331a6a52019-05-27 16:39:22 +02001756 status = config_init_stdio_encoding(config, preconfig);
1757 if (_PyStatus_EXCEPTION(status)) {
1758 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001759 }
1760
Victor Stinner62599762019-03-15 16:03:23 +01001761 if (config->argv.length < 1) {
1762 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001763 status = PyWideStringList_Append(&config->argv, L"");
1764 if (_PyStatus_EXCEPTION(status)) {
1765 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001766 }
1767 }
Victor Stinner870b0352019-05-17 03:15:12 +02001768
1769 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001770 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1771 L"default");
1772 if (_PyStatus_EXCEPTION(status)) {
1773 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001774 }
1775 }
1776
1777 if (config->configure_c_stdio < 0) {
1778 config->configure_c_stdio = 1;
1779 }
1780
Victor Stinner331a6a52019-05-27 16:39:22 +02001781 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001782}
Victor Stinner5ed69952018-11-06 15:59:52 +01001783
1784
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001785static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001786config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001787{
1788#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1789 /* don't translate newlines (\r\n <=> \n) */
1790 _setmode(fileno(stdin), O_BINARY);
1791 _setmode(fileno(stdout), O_BINARY);
1792 _setmode(fileno(stderr), O_BINARY);
1793#endif
1794
1795 if (!config->buffered_stdio) {
1796#ifdef HAVE_SETVBUF
1797 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1798 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1799 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1800#else /* !HAVE_SETVBUF */
1801 setbuf(stdin, (char *)NULL);
1802 setbuf(stdout, (char *)NULL);
1803 setbuf(stderr, (char *)NULL);
1804#endif /* !HAVE_SETVBUF */
1805 }
1806 else if (config->interactive) {
1807#ifdef MS_WINDOWS
1808 /* Doesn't have to have line-buffered -- use unbuffered */
1809 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1810 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1811#else /* !MS_WINDOWS */
1812#ifdef HAVE_SETVBUF
1813 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1814 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1815#endif /* HAVE_SETVBUF */
1816#endif /* !MS_WINDOWS */
1817 /* Leave stderr alone - it should be unbuffered anyway. */
1818 }
1819}
1820
1821
1822/* Write the configuration:
1823
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001824 - set Py_xxx global configuration variables
1825 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinnere81f6e62020-06-08 18:12:59 +02001826PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +02001827_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001828{
Victor Stinner331a6a52019-05-27 16:39:22 +02001829 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001830
1831 if (config->configure_c_stdio) {
1832 config_init_stdio(config);
1833 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001834
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001835 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001836 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001837 preconfig->isolated = config->isolated;
1838 preconfig->use_environment = config->use_environment;
1839 preconfig->dev_mode = config->dev_mode;
Victor Stinnere81f6e62020-06-08 18:12:59 +02001840
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02001841 if (_Py_SetArgcArgv(config->orig_argv.length,
1842 config->orig_argv.items) < 0)
Victor Stinnere81f6e62020-06-08 18:12:59 +02001843 {
1844 return _PyStatus_NO_MEMORY();
1845 }
1846 return _PyStatus_OK();
Victor Stinner5ed69952018-11-06 15:59:52 +01001847}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001848
1849
Victor Stinner331a6a52019-05-27 16:39:22 +02001850/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001851
1852static void
Victor Stinner2f549082019-03-29 15:13:46 +01001853config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001854{
Victor Stinner2f549082019-03-29 15:13:46 +01001855 FILE *f = error ? stderr : stdout;
1856
1857 fprintf(f, usage_line, program);
1858 if (error)
1859 fprintf(f, "Try `python -h' for more information.\n");
1860 else {
1861 fputs(usage_1, f);
1862 fputs(usage_2, f);
1863 fputs(usage_3, f);
1864 fprintf(f, usage_4, (wint_t)DELIM);
1865 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1866 fputs(usage_6, f);
1867 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001868}
1869
1870
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001871/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001872static PyStatus
1873config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001874 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001875{
Victor Stinner331a6a52019-05-27 16:39:22 +02001876 PyStatus status;
1877 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001878 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001879 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001880
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001881 _PyOS_ResetGetOpt();
1882 do {
1883 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001884 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001885 if (c == EOF) {
1886 break;
1887 }
1888
1889 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001890 if (config->run_command == NULL) {
1891 /* -c is the last option; following arguments
1892 that look like options are left for the
1893 command to interpret. */
1894 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1895 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1896 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001897 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001898 }
1899 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1900 command[len - 2] = '\n';
1901 command[len - 1] = 0;
1902 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001903 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001904 break;
1905 }
1906
1907 if (c == 'm') {
1908 /* -m is the last option; following arguments
1909 that look like options are left for the
1910 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001911 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001912 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1913 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001914 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001915 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001916 }
1917 break;
1918 }
1919
1920 switch (c) {
1921 case 0:
1922 // Handle long option.
1923 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001924 if (wcscmp(_PyOS_optarg, L"always") == 0
1925 || wcscmp(_PyOS_optarg, L"never") == 0
1926 || wcscmp(_PyOS_optarg, L"default") == 0)
1927 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001928 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1929 _PyOS_optarg);
1930 if (_PyStatus_EXCEPTION(status)) {
1931 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001932 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001933 } else {
1934 fprintf(stderr, "--check-hash-based-pycs must be one of "
1935 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001936 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001937 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001938 }
1939 break;
1940
1941 case 'b':
1942 config->bytes_warning++;
1943 break;
1944
1945 case 'd':
1946 config->parser_debug++;
1947 break;
1948
1949 case 'i':
1950 config->inspect++;
1951 config->interactive++;
1952 break;
1953
Victor Stinner6dcb5422019-03-05 02:44:12 +01001954 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001955 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001956 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001957 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001958 break;
1959
1960 /* case 'J': reserved for Jython */
1961
1962 case 'O':
1963 config->optimization_level++;
1964 break;
1965
1966 case 'B':
1967 config->write_bytecode = 0;
1968 break;
1969
1970 case 's':
1971 config->user_site_directory = 0;
1972 break;
1973
1974 case 'S':
1975 config->site_import = 0;
1976 break;
1977
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001978 case 't':
1979 /* ignored for backwards compatibility */
1980 break;
1981
1982 case 'u':
1983 config->buffered_stdio = 0;
1984 break;
1985
1986 case 'v':
1987 config->verbose++;
1988 break;
1989
1990 case 'x':
1991 config->skip_source_first_line = 1;
1992 break;
1993
1994 case 'h':
1995 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001996 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001997 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001998
1999 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01002000 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002001 break;
2002
2003 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002004 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2005 if (_PyStatus_EXCEPTION(status)) {
2006 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002007 }
2008 break;
2009
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002010 case 'q':
2011 config->quiet++;
2012 break;
2013
2014 case 'R':
2015 config->use_hash_seed = 0;
2016 break;
2017
2018 /* This space reserved for other options */
2019
2020 default:
2021 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002022 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002023 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002024 }
2025 } while (1);
2026
Victor Stinner2f549082019-03-29 15:13:46 +01002027 if (print_version) {
2028 printf("Python %s\n",
2029 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002030 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002031 }
2032
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002033 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002034 && _PyOS_optind < argv->length
2035 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002036 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002037 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002038 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002039 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002040 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002041 }
2042 }
2043
2044 if (config->run_command != NULL || config->run_module != NULL) {
2045 /* Backup _PyOS_optind */
2046 _PyOS_optind--;
2047 }
2048
Victor Stinnerae239f62019-05-16 17:02:56 +02002049 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002050
Victor Stinner331a6a52019-05-27 16:39:22 +02002051 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002052}
2053
2054
2055#ifdef MS_WINDOWS
2056# define WCSTOK wcstok_s
2057#else
2058# define WCSTOK wcstok
2059#endif
2060
2061/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002062static PyStatus
2063config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002064{
Victor Stinner331a6a52019-05-27 16:39:22 +02002065 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002066 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2067 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002068 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002069 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002070 if (_PyStatus_EXCEPTION(status)) {
2071 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002072 }
2073
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002074 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002075 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002076 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002077 }
2078
2079
2080 wchar_t *warning, *context = NULL;
2081 for (warning = WCSTOK(env, L",", &context);
2082 warning != NULL;
2083 warning = WCSTOK(NULL, L",", &context))
2084 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002085 status = PyWideStringList_Append(warnoptions, warning);
2086 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002087 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002088 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002089 }
2090 }
2091 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002092 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002093}
2094
2095
Victor Stinner331a6a52019-05-27 16:39:22 +02002096static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002097warnoptions_append(PyConfig *config, PyWideStringList *options,
2098 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002099{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002100 /* config_init_warnoptions() add existing config warnoptions at the end:
2101 ensure that the new option is not already present in this list to
2102 prevent change the options order whne config_init_warnoptions() is
2103 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002104 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002105 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002106 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002107 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002108 if (_PyWideStringList_Find(options, option)) {
2109 /* Already present: do nothing */
2110 return _PyStatus_OK();
2111 }
2112 return PyWideStringList_Append(options, option);
2113}
2114
2115
2116static PyStatus
2117warnoptions_extend(PyConfig *config, PyWideStringList *options,
2118 const PyWideStringList *options2)
2119{
2120 const Py_ssize_t len = options2->length;
2121 wchar_t *const *items = options2->items;
2122
2123 for (Py_ssize_t i = 0; i < len; i++) {
2124 PyStatus status = warnoptions_append(config, options, items[i]);
2125 if (_PyStatus_EXCEPTION(status)) {
2126 return status;
2127 }
2128 }
2129 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002130}
2131
2132
Victor Stinner331a6a52019-05-27 16:39:22 +02002133static PyStatus
2134config_init_warnoptions(PyConfig *config,
2135 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002136 const PyWideStringList *env_warnoptions,
2137 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002138{
Victor Stinner331a6a52019-05-27 16:39:22 +02002139 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002140 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002141
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002142 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002143 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002144 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002145 * - PyConfig.dev_mode: "default" filter
2146 * - PYTHONWARNINGS environment variable
2147 * - '-W' command line options
2148 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2149 * "default::BytesWarning" or "error::BytesWarning" filter
2150 * - early PySys_AddWarnOption() calls
2151 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002152 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002153 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2154 * module works on the basis of "the most recently added filter will be
2155 * checked first", we add the lowest precedence entries first so that later
2156 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002157 */
2158
Victor Stinner20004952019-03-26 02:31:11 +01002159 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002160 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002161 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002162 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002163 }
2164 }
2165
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002166 status = warnoptions_extend(config, &options, env_warnoptions);
2167 if (_PyStatus_EXCEPTION(status)) {
2168 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002169 }
2170
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002171 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2172 if (_PyStatus_EXCEPTION(status)) {
2173 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002174 }
2175
2176 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2177 * don't even try to emit a warning, so we skip setting the filter in that
2178 * case.
2179 */
2180 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002181 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002182 if (config->bytes_warning> 1) {
2183 filter = L"error::BytesWarning";
2184 }
2185 else {
2186 filter = L"default::BytesWarning";
2187 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002188 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002189 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002190 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002191 }
2192 }
Victor Stinner120b7072019-08-23 18:03:08 +01002193
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002194 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002195 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002196 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002197 }
2198
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002199 /* Always add all PyConfig.warnoptions options */
2200 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2201 if (_PyStatus_EXCEPTION(status)) {
2202 goto error;
2203 }
2204
2205 _PyWideStringList_Clear(&config->warnoptions);
2206 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002207 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002208
2209error:
2210 _PyWideStringList_Clear(&options);
2211 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002212}
2213
2214
Victor Stinner331a6a52019-05-27 16:39:22 +02002215static PyStatus
2216config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002217{
Victor Stinner331a6a52019-05-27 16:39:22 +02002218 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002219 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002220
Victor Stinner74f65682019-03-15 15:08:05 +01002221 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002222 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002223 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002224 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2225 if (_PyStatus_EXCEPTION(status)) {
2226 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002227 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002228 }
2229 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002230 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002231 slice.length = cmdline_argv->length - opt_index;
2232 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002233 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2234 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002235 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002236 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002237 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002238
2239 wchar_t *arg0 = NULL;
2240 if (config->run_command != NULL) {
2241 /* Force sys.argv[0] = '-c' */
2242 arg0 = L"-c";
2243 }
2244 else if (config->run_module != NULL) {
2245 /* Force sys.argv[0] = '-m'*/
2246 arg0 = L"-m";
2247 }
Victor Stinner3939c322019-06-25 15:02:43 +02002248
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002249 if (arg0 != NULL) {
2250 arg0 = _PyMem_RawWcsdup(arg0);
2251 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002252 _PyWideStringList_Clear(&config_argv);
2253 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002254 }
2255
Victor Stinnerfa153762019-03-20 04:25:38 +01002256 PyMem_RawFree(config_argv.items[0]);
2257 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002258 }
2259
Victor Stinner331a6a52019-05-27 16:39:22 +02002260 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002261 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002262 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002263}
2264
2265
Victor Stinner331a6a52019-05-27 16:39:22 +02002266static PyStatus
2267core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002268{
Victor Stinner331a6a52019-05-27 16:39:22 +02002269 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002270
Victor Stinnercab5d072019-05-17 19:01:14 +02002271 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002272 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2273 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002274 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002275 }
2276
Victor Stinner331a6a52019-05-27 16:39:22 +02002277 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002278
2279 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2280 if (_PyStatus_EXCEPTION(status)) {
2281 return status;
2282 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002283
Victor Stinner331a6a52019-05-27 16:39:22 +02002284 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002285
Victor Stinner331a6a52019-05-27 16:39:22 +02002286 status = _PyPreCmdline_Read(precmdline, &preconfig);
2287 if (_PyStatus_EXCEPTION(status)) {
2288 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002289 }
2290
Victor Stinner331a6a52019-05-27 16:39:22 +02002291 status = _PyPreCmdline_SetConfig(precmdline, config);
2292 if (_PyStatus_EXCEPTION(status)) {
2293 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002294 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002295 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002296}
2297
2298
Victor Stinner3939c322019-06-25 15:02:43 +02002299/* Get run_filename absolute path */
2300static PyStatus
2301config_run_filename_abspath(PyConfig *config)
2302{
2303 if (!config->run_filename) {
2304 return _PyStatus_OK();
2305 }
2306
2307#ifndef MS_WINDOWS
2308 if (_Py_isabs(config->run_filename)) {
2309 /* path is already absolute */
2310 return _PyStatus_OK();
2311 }
2312#endif
2313
2314 wchar_t *abs_filename;
2315 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2316 /* failed to get the absolute path of the command line filename:
2317 ignore the error, keep the relative path */
2318 return _PyStatus_OK();
2319 }
2320 if (abs_filename == NULL) {
2321 return _PyStatus_NO_MEMORY();
2322 }
2323
2324 PyMem_RawFree(config->run_filename);
2325 config->run_filename = abs_filename;
2326 return _PyStatus_OK();
2327}
2328
2329
Victor Stinner331a6a52019-05-27 16:39:22 +02002330static PyStatus
2331config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002332{
Victor Stinner331a6a52019-05-27 16:39:22 +02002333 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002334 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2335 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2336 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002337
Victor Stinnerae239f62019-05-16 17:02:56 +02002338 if (config->parse_argv < 0) {
2339 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002340 }
Victor Stinner870b0352019-05-17 03:15:12 +02002341
Victor Stinnerfed02e12019-05-17 11:12:09 +02002342 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002343 status = config_init_program_name(config);
2344 if (_PyStatus_EXCEPTION(status)) {
2345 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002346 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002347 }
Victor Stinner2f549082019-03-29 15:13:46 +01002348
Victor Stinnerae239f62019-05-16 17:02:56 +02002349 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002350 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002351 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2352 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002353 goto done;
2354 }
2355
Victor Stinner3939c322019-06-25 15:02:43 +02002356 status = config_run_filename_abspath(config);
2357 if (_PyStatus_EXCEPTION(status)) {
2358 goto done;
2359 }
2360
Victor Stinner331a6a52019-05-27 16:39:22 +02002361 status = config_update_argv(config, opt_index);
2362 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002363 goto done;
2364 }
Victor Stinner2f549082019-03-29 15:13:46 +01002365 }
Victor Stinner3939c322019-06-25 15:02:43 +02002366 else {
2367 status = config_run_filename_abspath(config);
2368 if (_PyStatus_EXCEPTION(status)) {
2369 goto done;
2370 }
2371 }
Victor Stinner2f549082019-03-29 15:13:46 +01002372
Victor Stinner2f549082019-03-29 15:13:46 +01002373 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002374 status = config_init_env_warnoptions(config, &env_warnoptions);
2375 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002376 goto done;
2377 }
2378 }
2379
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002380 /* Handle early PySys_AddWarnOption() calls */
2381 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2382 if (_PyStatus_EXCEPTION(status)) {
2383 goto done;
2384 }
2385
Victor Stinner331a6a52019-05-27 16:39:22 +02002386 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002387 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002388 &env_warnoptions,
2389 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002390 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002391 goto done;
2392 }
2393
Victor Stinner331a6a52019-05-27 16:39:22 +02002394 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002395
2396done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002397 _PyWideStringList_Clear(&cmdline_warnoptions);
2398 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002399 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002400 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002401}
2402
2403
Victor Stinner331a6a52019-05-27 16:39:22 +02002404PyStatus
2405_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002406{
Victor Stinner331a6a52019-05-27 16:39:22 +02002407 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2408 if (_PyStatus_EXCEPTION(status)) {
2409 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002410 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002411
Victor Stinner5f38b842019-05-01 02:30:12 +02002412 return _PyArgv_AsWstrList(args, &config->argv);
2413}
2414
2415
Victor Stinner70005ac2019-05-02 15:25:34 -04002416/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2417 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002418PyStatus
2419PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002420{
2421 _PyArgv args = {
2422 .argc = argc,
2423 .use_bytes_argv = 1,
2424 .bytes_argv = argv,
2425 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002426 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002427}
2428
2429
Victor Stinner331a6a52019-05-27 16:39:22 +02002430PyStatus
2431PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002432{
2433 _PyArgv args = {
2434 .argc = argc,
2435 .use_bytes_argv = 0,
2436 .bytes_argv = NULL,
2437 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002438 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002439}
2440
2441
Victor Stinner36242fd2019-07-01 19:13:50 +02002442PyStatus
2443PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2444 Py_ssize_t length, wchar_t **items)
2445{
2446 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2447 if (_PyStatus_EXCEPTION(status)) {
2448 return status;
2449 }
2450
2451 PyWideStringList list2 = {.length = length, .items = items};
2452 if (_PyWideStringList_Copy(list, &list2) < 0) {
2453 return _PyStatus_NO_MEMORY();
2454 }
2455 return _PyStatus_OK();
2456}
2457
2458
Victor Stinner331a6a52019-05-27 16:39:22 +02002459/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002460
2461 * Command line arguments
2462 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002463 * Py_xxx global configuration variables
2464
2465 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002466PyStatus
2467PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002468{
Victor Stinner331a6a52019-05-27 16:39:22 +02002469 PyStatus status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002470
Victor Stinner331a6a52019-05-27 16:39:22 +02002471 status = _Py_PreInitializeFromConfig(config, NULL);
2472 if (_PyStatus_EXCEPTION(status)) {
2473 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002474 }
2475
Victor Stinner331a6a52019-05-27 16:39:22 +02002476 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002477
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002478 if (config->orig_argv.length == 0
Victor Stinnere81f6e62020-06-08 18:12:59 +02002479 && !(config->argv.length == 1
2480 && wcscmp(config->argv.items[0], L"") == 0))
2481 {
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002482 if (_PyWideStringList_Copy(&config->orig_argv, &config->argv) < 0) {
Victor Stinnere81f6e62020-06-08 18:12:59 +02002483 return _PyStatus_NO_MEMORY();
2484 }
Victor Stinnercab5d072019-05-17 19:01:14 +02002485 }
2486
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002487 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002488 status = core_read_precmdline(config, &precmdline);
2489 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002490 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002491 }
2492
Victor Stinner870b0352019-05-17 03:15:12 +02002493 assert(config->isolated >= 0);
2494 if (config->isolated) {
2495 config->use_environment = 0;
2496 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002497 }
2498
Victor Stinner331a6a52019-05-27 16:39:22 +02002499 status = config_read_cmdline(config);
2500 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002501 goto done;
2502 }
2503
Victor Stinner120b7072019-08-23 18:03:08 +01002504 /* Handle early PySys_AddXOption() calls */
2505 status = _PySys_ReadPreinitXOptions(config);
2506 if (_PyStatus_EXCEPTION(status)) {
2507 goto done;
2508 }
2509
Victor Stinner331a6a52019-05-27 16:39:22 +02002510 status = config_read(config);
2511 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002512 goto done;
2513 }
2514
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002515 /* Check config consistency */
2516 assert(config->isolated >= 0);
2517 assert(config->use_environment >= 0);
2518 assert(config->dev_mode >= 0);
2519 assert(config->install_signal_handlers >= 0);
2520 assert(config->use_hash_seed >= 0);
2521 assert(config->faulthandler >= 0);
2522 assert(config->tracemalloc >= 0);
2523 assert(config->site_import >= 0);
2524 assert(config->bytes_warning >= 0);
2525 assert(config->inspect >= 0);
2526 assert(config->interactive >= 0);
2527 assert(config->optimization_level >= 0);
2528 assert(config->parser_debug >= 0);
2529 assert(config->write_bytecode >= 0);
2530 assert(config->verbose >= 0);
2531 assert(config->quiet >= 0);
2532 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002533 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002534 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002535 assert(config->buffered_stdio >= 0);
2536 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002537 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002538 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2539 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002540 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2541 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2542 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002543 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002544 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002545 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002546 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002547 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002548 assert(config->prefix != NULL);
2549 assert(config->base_prefix != NULL);
2550 assert(config->exec_prefix != NULL);
2551 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002552 }
Sandro Mani8f023a22020-06-08 17:28:11 +02002553 assert(config->platlibdir != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002554 assert(config->filesystem_encoding != NULL);
2555 assert(config->filesystem_errors != NULL);
2556 assert(config->stdio_encoding != NULL);
2557 assert(config->stdio_errors != NULL);
2558#ifdef MS_WINDOWS
2559 assert(config->legacy_windows_stdio >= 0);
2560#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002561 /* -c and -m options are exclusive */
2562 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002563 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002564 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002565 assert(config->pathconfig_warnings >= 0);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002566 assert(_PyWideStringList_CheckConsistency(&config->orig_argv));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002567
Victor Stinner331a6a52019-05-27 16:39:22 +02002568 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002569
2570done:
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002571 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002572 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002573}
Victor Stinner1075d162019-03-25 23:19:57 +01002574
2575
2576PyObject*
2577_Py_GetConfigsAsDict(void)
2578{
Victor Stinner331a6a52019-05-27 16:39:22 +02002579 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002580 PyObject *dict = NULL;
2581
Victor Stinner331a6a52019-05-27 16:39:22 +02002582 result = PyDict_New();
2583 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002584 goto error;
2585 }
2586
Victor Stinner331a6a52019-05-27 16:39:22 +02002587 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002588 dict = _Py_GetGlobalVariablesAsDict();
2589 if (dict == NULL) {
2590 goto error;
2591 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002592 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002593 goto error;
2594 }
2595 Py_CLEAR(dict);
2596
2597 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002598 PyThreadState *tstate = _PyThreadState_GET();
2599 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002600 dict = _PyPreConfig_AsDict(pre_config);
2601 if (dict == NULL) {
2602 goto error;
2603 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002604 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002605 goto error;
2606 }
2607 Py_CLEAR(dict);
2608
2609 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002610 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinner331a6a52019-05-27 16:39:22 +02002611 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002612 if (dict == NULL) {
2613 goto error;
2614 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002615 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002616 goto error;
2617 }
2618 Py_CLEAR(dict);
2619
Victor Stinner8f427482020-07-08 00:20:37 +02002620 /* path config */
2621 dict = _PyPathConfig_AsDict();
2622 if (dict == NULL) {
2623 goto error;
2624 }
2625 if (PyDict_SetItemString(result, "path_config", dict) < 0) {
2626 goto error;
2627 }
2628 Py_CLEAR(dict);
2629
Victor Stinner331a6a52019-05-27 16:39:22 +02002630 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002631
2632error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002633 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002634 Py_XDECREF(dict);
2635 return NULL;
2636}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002637
2638
2639static void
2640init_dump_ascii_wstr(const wchar_t *str)
2641{
2642 if (str == NULL) {
2643 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002644 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002645 }
2646
2647 PySys_WriteStderr("'");
2648 for (; *str != L'\0'; str++) {
Victor Stinner640e8e12020-09-09 12:07:17 +02002649 unsigned int ch = (unsigned int)*str;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002650 if (ch == L'\'') {
2651 PySys_WriteStderr("\\'");
2652 } else if (0x20 <= ch && ch < 0x7f) {
Samuel Marksc3229482020-09-21 18:35:17 +10002653 PySys_WriteStderr("%c", ch);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002654 }
2655 else if (ch <= 0xff) {
2656 PySys_WriteStderr("\\x%02x", ch);
2657 }
2658#if SIZEOF_WCHAR_T > 2
2659 else if (ch > 0xffff) {
2660 PySys_WriteStderr("\\U%08x", ch);
2661 }
2662#endif
2663 else {
2664 PySys_WriteStderr("\\u%04x", ch);
2665 }
2666 }
2667 PySys_WriteStderr("'");
2668}
2669
2670
2671/* Dump the Python path configuration into sys.stderr */
2672void
2673_Py_DumpPathConfig(PyThreadState *tstate)
2674{
2675 PyObject *exc_type, *exc_value, *exc_tb;
2676 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2677
2678 PySys_WriteStderr("Python path configuration:\n");
2679
2680#define DUMP_CONFIG(NAME, FIELD) \
2681 do { \
2682 PySys_WriteStderr(" " NAME " = "); \
2683 init_dump_ascii_wstr(config->FIELD); \
2684 PySys_WriteStderr("\n"); \
2685 } while (0)
2686
Victor Stinnerda7933e2020-04-13 03:04:28 +02002687 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002688 DUMP_CONFIG("PYTHONHOME", home);
2689 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2690 DUMP_CONFIG("program name", program_name);
2691 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2692 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2693 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2694 PySys_WriteStderr(" import site = %i\n", config->site_import);
2695#undef DUMP_CONFIG
2696
2697#define DUMP_SYS(NAME) \
2698 do { \
2699 obj = PySys_GetObject(#NAME); \
2700 PySys_FormatStderr(" sys.%s = ", #NAME); \
2701 if (obj != NULL) { \
2702 PySys_FormatStderr("%A", obj); \
2703 } \
2704 else { \
2705 PySys_WriteStderr("(not set)"); \
2706 } \
2707 PySys_FormatStderr("\n"); \
2708 } while (0)
2709
2710 PyObject *obj;
2711 DUMP_SYS(_base_executable);
2712 DUMP_SYS(base_prefix);
2713 DUMP_SYS(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +02002714 DUMP_SYS(platlibdir);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002715 DUMP_SYS(executable);
2716 DUMP_SYS(prefix);
2717 DUMP_SYS(exec_prefix);
2718#undef DUMP_SYS
2719
2720 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2721 if (sys_path != NULL && PyList_Check(sys_path)) {
2722 PySys_WriteStderr(" sys.path = [\n");
2723 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2724 for (Py_ssize_t i=0; i < len; i++) {
2725 PyObject *path = PyList_GET_ITEM(sys_path, i);
2726 PySys_FormatStderr(" %A,\n", path);
2727 }
2728 PySys_WriteStderr(" ]\n");
2729 }
2730
2731 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2732}