blob: 7bb28ed01f164aaaec3f4fb294a16d25b35e2ff8 [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 Stinner4b9aad42020-11-02 16:49:54 +0100546// _PyConfig_Write() calls _Py_SetArgcArgv() with PyConfig.orig_argv.
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100547void
548Py_GetArgcArgv(int *argc, wchar_t ***argv)
549{
Victor Stinner74f65682019-03-15 15:08:05 +0100550 *argc = (int)orig_argv.length;
551 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100552}
553
554
Victor Stinner331a6a52019-05-27 16:39:22 +0200555/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100556
557#define DECODE_LOCALE_ERR(NAME, LEN) \
558 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200559 ? _PyStatus_ERR("cannot decode " NAME) \
560 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100561
Victor Stinner441b10c2019-09-28 04:28:35 +0200562
Victor Stinner6c785c02018-08-01 17:56:14 +0200563/* Free memory allocated in config, but don't clear all attributes */
564void
Victor Stinner331a6a52019-05-27 16:39:22 +0200565PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200566{
567#define CLEAR(ATTR) \
568 do { \
569 PyMem_RawFree(ATTR); \
570 ATTR = NULL; \
571 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200572
573 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200574 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200575 CLEAR(config->home);
576 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200577
Victor Stinner331a6a52019-05-27 16:39:22 +0200578 _PyWideStringList_Clear(&config->argv);
579 _PyWideStringList_Clear(&config->warnoptions);
580 _PyWideStringList_Clear(&config->xoptions);
581 _PyWideStringList_Clear(&config->module_search_paths);
582 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200583
584 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700585 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200586 CLEAR(config->prefix);
587 CLEAR(config->base_prefix);
588 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200589 CLEAR(config->base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200590 CLEAR(config->platlibdir);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200591
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200592 CLEAR(config->filesystem_encoding);
593 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200594 CLEAR(config->stdio_encoding);
595 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100596 CLEAR(config->run_command);
597 CLEAR(config->run_module);
598 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400599 CLEAR(config->check_hash_pycs_mode);
Victor Stinnere2d47a02020-06-15 16:27:47 +0200600
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200601 _PyWideStringList_Clear(&config->orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200602#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200603}
604
605
Victor Stinner8462a492019-10-01 12:06:16 +0200606void
Victor Stinner331a6a52019-05-27 16:39:22 +0200607_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200608{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200609 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200610
Victor Stinner022be022019-05-22 23:58:50 +0200611 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200612 config->isolated = -1;
613 config->use_environment = -1;
614 config->dev_mode = -1;
615 config->install_signal_handlers = 1;
616 config->use_hash_seed = -1;
617 config->faulthandler = -1;
618 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200619 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200620 config->parse_argv = 0;
621 config->site_import = -1;
622 config->bytes_warning = -1;
623 config->inspect = -1;
624 config->interactive = -1;
625 config->optimization_level = -1;
626 config->parser_debug= -1;
627 config->write_bytecode = -1;
628 config->verbose = -1;
629 config->quiet = -1;
630 config->user_site_directory = -1;
631 config->configure_c_stdio = 0;
632 config->buffered_stdio = -1;
633 config->_install_importlib = 1;
634 config->check_hash_pycs_mode = NULL;
635 config->pathconfig_warnings = -1;
636 config->_init_main = 1;
Victor Stinner252346a2020-05-01 11:33:44 +0200637 config->_isolated_interpreter = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200638#ifdef MS_WINDOWS
639 config->legacy_windows_stdio = -1;
640#endif
641}
642
643
Victor Stinner8462a492019-10-01 12:06:16 +0200644static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200645config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200646{
Victor Stinner8462a492019-10-01 12:06:16 +0200647 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200648
649 config->isolated = 0;
650 config->use_environment = 1;
651 config->site_import = 1;
652 config->bytes_warning = 0;
653 config->inspect = 0;
654 config->interactive = 0;
655 config->optimization_level = 0;
656 config->parser_debug= 0;
657 config->write_bytecode = 1;
658 config->verbose = 0;
659 config->quiet = 0;
660 config->user_site_directory = 1;
661 config->buffered_stdio = 1;
662 config->pathconfig_warnings = 1;
663#ifdef MS_WINDOWS
664 config->legacy_windows_stdio = 0;
665#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200666}
667
668
Victor Stinner8462a492019-10-01 12:06:16 +0200669void
Victor Stinner331a6a52019-05-27 16:39:22 +0200670PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200671{
Victor Stinner8462a492019-10-01 12:06:16 +0200672 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200673
Victor Stinner022be022019-05-22 23:58:50 +0200674 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200675 config->configure_c_stdio = 1;
676 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200677}
678
679
Victor Stinner8462a492019-10-01 12:06:16 +0200680void
Victor Stinner331a6a52019-05-27 16:39:22 +0200681PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200682{
Victor Stinner8462a492019-10-01 12:06:16 +0200683 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200684
Victor Stinner022be022019-05-22 23:58:50 +0200685 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200686 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200687 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200688 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200689 config->dev_mode = 0;
690 config->install_signal_handlers = 0;
691 config->use_hash_seed = 0;
692 config->faulthandler = 0;
693 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200694 config->pathconfig_warnings = 0;
695#ifdef MS_WINDOWS
696 config->legacy_windows_stdio = 0;
697#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200698}
699
700
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200701/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200702PyStatus
703PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200704{
Victor Stinner331a6a52019-05-27 16:39:22 +0200705 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
706 if (_PyStatus_EXCEPTION(status)) {
707 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200708 }
709
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200710 wchar_t *str2;
711 if (str != NULL) {
712 str2 = _PyMem_RawWcsdup(str);
713 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200714 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200715 }
716 }
717 else {
718 str2 = NULL;
719 }
720 PyMem_RawFree(*config_str);
721 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200722 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200723}
724
725
Victor Stinner331a6a52019-05-27 16:39:22 +0200726static PyStatus
727config_set_bytes_string(PyConfig *config, wchar_t **config_str,
728 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200729{
Victor Stinner331a6a52019-05-27 16:39:22 +0200730 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
731 if (_PyStatus_EXCEPTION(status)) {
732 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400733 }
734
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200735 wchar_t *str2;
736 if (str != NULL) {
737 size_t len;
738 str2 = Py_DecodeLocale(str, &len);
739 if (str2 == NULL) {
740 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200741 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200742 }
743 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200744 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200745 }
746 }
747 }
748 else {
749 str2 = NULL;
750 }
751 PyMem_RawFree(*config_str);
752 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200753 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200754}
755
756
Victor Stinner331a6a52019-05-27 16:39:22 +0200757#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
758 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400759
760
Victor Stinner70005ac2019-05-02 15:25:34 -0400761/* Decode str using Py_DecodeLocale() and set the result into *config_str.
762 Pre-initialize Python if needed to ensure that encodings are properly
763 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200764PyStatus
765PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner710e8262020-10-31 01:02:09 +0100766 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400767{
Victor Stinner331a6a52019-05-27 16:39:22 +0200768 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400769}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200770
771
Victor Stinner331a6a52019-05-27 16:39:22 +0200772PyStatus
773_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200774{
Victor Stinner331a6a52019-05-27 16:39:22 +0200775 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200776
Victor Stinner331a6a52019-05-27 16:39:22 +0200777 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200778
779#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200780#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200781 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200782 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
783 if (_PyStatus_EXCEPTION(status)) { \
784 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200785 } \
786 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100787#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200788 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200789 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200790 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200791 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200792 } while (0)
793
Victor Stinner6d1c4672019-05-20 11:02:00 +0200794 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100795 COPY_ATTR(isolated);
796 COPY_ATTR(use_environment);
797 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200798 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200799 COPY_ATTR(use_hash_seed);
800 COPY_ATTR(hash_seed);
801 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200802 COPY_ATTR(faulthandler);
803 COPY_ATTR(tracemalloc);
804 COPY_ATTR(import_time);
805 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200806 COPY_ATTR(dump_refs);
807 COPY_ATTR(malloc_stats);
808
Victor Stinner124b9eb2018-08-29 01:29:06 +0200809 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200810 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200811 COPY_WSTR_ATTR(home);
812 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200813
Victor Stinnerae239f62019-05-16 17:02:56 +0200814 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100815 COPY_WSTRLIST(argv);
816 COPY_WSTRLIST(warnoptions);
817 COPY_WSTRLIST(xoptions);
818 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200819 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200820
Victor Stinner124b9eb2018-08-29 01:29:06 +0200821 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700822 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200823 COPY_WSTR_ATTR(prefix);
824 COPY_WSTR_ATTR(base_prefix);
825 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200826 COPY_WSTR_ATTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200827 COPY_WSTR_ATTR(platlibdir);
Victor Stinner6c785c02018-08-01 17:56:14 +0200828
Victor Stinner6c785c02018-08-01 17:56:14 +0200829 COPY_ATTR(site_import);
830 COPY_ATTR(bytes_warning);
831 COPY_ATTR(inspect);
832 COPY_ATTR(interactive);
833 COPY_ATTR(optimization_level);
834 COPY_ATTR(parser_debug);
835 COPY_ATTR(write_bytecode);
836 COPY_ATTR(verbose);
837 COPY_ATTR(quiet);
838 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200839 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200840 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400841 COPY_WSTR_ATTR(filesystem_encoding);
842 COPY_WSTR_ATTR(filesystem_errors);
843 COPY_WSTR_ATTR(stdio_encoding);
844 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200845#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200846 COPY_ATTR(legacy_windows_stdio);
847#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100848 COPY_ATTR(skip_source_first_line);
849 COPY_WSTR_ATTR(run_command);
850 COPY_WSTR_ATTR(run_module);
851 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400852 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200853 COPY_ATTR(pathconfig_warnings);
854 COPY_ATTR(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200855 COPY_ATTR(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200856 COPY_WSTRLIST(orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200857
858#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200859#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200860#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200861 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200862}
863
864
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100865static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200866config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100867{
Victor Stinner8f427482020-07-08 00:20:37 +0200868 PyObject *dict = PyDict_New();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100869 if (dict == NULL) {
870 return NULL;
871 }
872
873#define SET_ITEM(KEY, EXPR) \
874 do { \
875 PyObject *obj = (EXPR); \
876 if (obj == NULL) { \
877 goto fail; \
878 } \
879 int res = PyDict_SetItemString(dict, (KEY), obj); \
880 Py_DECREF(obj); \
881 if (res < 0) { \
882 goto fail; \
883 } \
884 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100885#define SET_ITEM_INT(ATTR) \
886 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
887#define SET_ITEM_UINT(ATTR) \
888 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100889#define FROM_WSTRING(STR) \
890 ((STR != NULL) ? \
891 PyUnicode_FromWideChar(STR, -1) \
892 : (Py_INCREF(Py_None), Py_None))
893#define SET_ITEM_WSTR(ATTR) \
894 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
895#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200896 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100897
Victor Stinner6d1c4672019-05-20 11:02:00 +0200898 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100899 SET_ITEM_INT(isolated);
900 SET_ITEM_INT(use_environment);
901 SET_ITEM_INT(dev_mode);
902 SET_ITEM_INT(install_signal_handlers);
903 SET_ITEM_INT(use_hash_seed);
904 SET_ITEM_UINT(hash_seed);
905 SET_ITEM_INT(faulthandler);
906 SET_ITEM_INT(tracemalloc);
907 SET_ITEM_INT(import_time);
908 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100909 SET_ITEM_INT(dump_refs);
910 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400911 SET_ITEM_WSTR(filesystem_encoding);
912 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100913 SET_ITEM_WSTR(pycache_prefix);
914 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200915 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100916 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100917 SET_ITEM_WSTRLIST(xoptions);
918 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200919 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100920 SET_ITEM_WSTR(home);
921 SET_ITEM_WSTRLIST(module_search_paths);
922 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700923 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100924 SET_ITEM_WSTR(prefix);
925 SET_ITEM_WSTR(base_prefix);
926 SET_ITEM_WSTR(exec_prefix);
927 SET_ITEM_WSTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200928 SET_ITEM_WSTR(platlibdir);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100929 SET_ITEM_INT(site_import);
930 SET_ITEM_INT(bytes_warning);
931 SET_ITEM_INT(inspect);
932 SET_ITEM_INT(interactive);
933 SET_ITEM_INT(optimization_level);
934 SET_ITEM_INT(parser_debug);
935 SET_ITEM_INT(write_bytecode);
936 SET_ITEM_INT(verbose);
937 SET_ITEM_INT(quiet);
938 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200939 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100940 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400941 SET_ITEM_WSTR(stdio_encoding);
942 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100943#ifdef MS_WINDOWS
944 SET_ITEM_INT(legacy_windows_stdio);
945#endif
946 SET_ITEM_INT(skip_source_first_line);
947 SET_ITEM_WSTR(run_command);
948 SET_ITEM_WSTR(run_module);
949 SET_ITEM_WSTR(run_filename);
950 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400951 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200952 SET_ITEM_INT(pathconfig_warnings);
953 SET_ITEM_INT(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200954 SET_ITEM_INT(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200955 SET_ITEM_WSTRLIST(orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100956
957 return dict;
958
959fail:
960 Py_DECREF(dict);
961 return NULL;
962
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100963#undef FROM_WSTRING
964#undef SET_ITEM
965#undef SET_ITEM_INT
966#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100967#undef SET_ITEM_WSTR
968#undef SET_ITEM_WSTRLIST
969}
970
971
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100972static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200973config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200974{
Victor Stinner20004952019-03-26 02:31:11 +0100975 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200976}
977
978
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100979/* Get a copy of the environment variable as wchar_t*.
980 Return 0 on success, but *dest can be NULL.
981 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200982static PyStatus
983config_get_env_dup(PyConfig *config,
984 wchar_t **dest,
985 wchar_t *wname, char *name,
986 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200987{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200988 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100989 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200990
Victor Stinner20004952019-03-26 02:31:11 +0100991 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200992 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200993 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200994 }
995
996#ifdef MS_WINDOWS
997 const wchar_t *var = _wgetenv(wname);
998 if (!var || var[0] == '\0') {
999 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001000 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001001 }
1002
Victor Stinner331a6a52019-05-27 16:39:22 +02001003 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +02001004#else
1005 const char *var = getenv(name);
1006 if (!var || var[0] == '\0') {
1007 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001008 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001009 }
1010
Victor Stinner331a6a52019-05-27 16:39:22 +02001011 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001012#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001013}
1014
1015
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001016#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001017 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001018
1019
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001020static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001021config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001022{
Victor Stinner022be022019-05-22 23:58:50 +02001023 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1024 /* Python and Isolated configuration ignore global variables */
1025 return;
1026 }
1027
Victor Stinner6c785c02018-08-01 17:56:14 +02001028#define COPY_FLAG(ATTR, VALUE) \
1029 if (config->ATTR == -1) { \
1030 config->ATTR = VALUE; \
1031 }
1032#define COPY_NOT_FLAG(ATTR, VALUE) \
1033 if (config->ATTR == -1) { \
1034 config->ATTR = !(VALUE); \
1035 }
1036
Victor Stinner20004952019-03-26 02:31:11 +01001037 COPY_FLAG(isolated, Py_IsolatedFlag);
1038 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001039 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1040 COPY_FLAG(inspect, Py_InspectFlag);
1041 COPY_FLAG(interactive, Py_InteractiveFlag);
1042 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1043 COPY_FLAG(parser_debug, Py_DebugFlag);
1044 COPY_FLAG(verbose, Py_VerboseFlag);
1045 COPY_FLAG(quiet, Py_QuietFlag);
1046#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001047 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1048#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001049 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001050
Victor Stinner6c785c02018-08-01 17:56:14 +02001051 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1052 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1053 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1054 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1055
Victor Stinner6c785c02018-08-01 17:56:14 +02001056#undef COPY_FLAG
1057#undef COPY_NOT_FLAG
1058}
1059
1060
1061/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001062static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001063config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001064{
1065#define COPY_FLAG(ATTR, VAR) \
1066 if (config->ATTR != -1) { \
1067 VAR = config->ATTR; \
1068 }
1069#define COPY_NOT_FLAG(ATTR, VAR) \
1070 if (config->ATTR != -1) { \
1071 VAR = !config->ATTR; \
1072 }
1073
Victor Stinner20004952019-03-26 02:31:11 +01001074 COPY_FLAG(isolated, Py_IsolatedFlag);
1075 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001076 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1077 COPY_FLAG(inspect, Py_InspectFlag);
1078 COPY_FLAG(interactive, Py_InteractiveFlag);
1079 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1080 COPY_FLAG(parser_debug, Py_DebugFlag);
1081 COPY_FLAG(verbose, Py_VerboseFlag);
1082 COPY_FLAG(quiet, Py_QuietFlag);
1083#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001084 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1085#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001086 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001087
Victor Stinner6c785c02018-08-01 17:56:14 +02001088 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1089 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1090 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1091 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1092
Victor Stinner6c785c02018-08-01 17:56:14 +02001093 /* Random or non-zero hash seed */
1094 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1095 config->hash_seed != 0);
1096
1097#undef COPY_FLAG
1098#undef COPY_NOT_FLAG
1099}
1100
1101
1102/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1103 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001104static PyStatus
1105config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001106{
Victor Stinner331a6a52019-05-27 16:39:22 +02001107 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001108
Victor Stinner6c785c02018-08-01 17:56:14 +02001109 /* If Py_SetProgramName() was called, use its value */
1110 const wchar_t *program_name = _Py_path_config.program_name;
1111 if (program_name != NULL) {
1112 config->program_name = _PyMem_RawWcsdup(program_name);
1113 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001114 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001115 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001116 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001117 }
1118
1119#ifdef __APPLE__
1120 /* On MacOS X, when the Python interpreter is embedded in an
1121 application bundle, it gets executed by a bootstrapping script
1122 that does os.execve() with an argv[0] that's different from the
1123 actual Python executable. This is needed to keep the Finder happy,
1124 or rather, to work around Apple's overly strict requirements of
1125 the process name. However, we still need a usable sys.executable,
1126 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001127 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001128 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001129 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001130 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001131 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1132 "PYTHONEXECUTABLE environment variable");
1133 if (_PyStatus_EXCEPTION(status)) {
1134 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001135 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001136 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001137 }
1138#ifdef WITH_NEXT_FRAMEWORK
1139 else {
1140 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1141 if (pyvenv_launcher && *pyvenv_launcher) {
1142 /* Used by Mac/Tools/pythonw.c to forward
1143 * the argv0 of the stub executable
1144 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001145 status = CONFIG_SET_BYTES_STR(config,
1146 &config->program_name,
1147 pyvenv_launcher,
1148 "__PYVENV_LAUNCHER__ environment variable");
1149 if (_PyStatus_EXCEPTION(status)) {
1150 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001151 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001152
1153 /*
1154 * This environment variable is used to communicate between
1155 * the stub launcher and the real interpreter and isn't needed
1156 * beyond this point.
1157 *
1158 * Clean up to avoid problems when launching other programs
1159 * later on.
1160 */
1161 (void)unsetenv("__PYVENV_LAUNCHER__");
1162
Victor Stinner331a6a52019-05-27 16:39:22 +02001163 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001164 }
1165 }
1166#endif /* WITH_NEXT_FRAMEWORK */
1167#endif /* __APPLE__ */
1168
Victor Stinnerfed02e12019-05-17 11:12:09 +02001169 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001170 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001171 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1172 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1173 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001174 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001175 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001176 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001177 }
1178
Victor Stinnerfed02e12019-05-17 11:12:09 +02001179 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001180#ifdef MS_WINDOWS
1181 const wchar_t *default_program_name = L"python";
1182#else
1183 const wchar_t *default_program_name = L"python3";
1184#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001185 status = PyConfig_SetString(config, &config->program_name,
1186 default_program_name);
1187 if (_PyStatus_EXCEPTION(status)) {
1188 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001189 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001190 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001191}
1192
Victor Stinner331a6a52019-05-27 16:39:22 +02001193static PyStatus
1194config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001195{
1196 assert(config->executable == NULL);
1197
1198 /* If Py_SetProgramFullPath() was called, use its value */
1199 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1200 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001201 PyStatus status = PyConfig_SetString(config,
1202 &config->executable,
1203 program_full_path);
1204 if (_PyStatus_EXCEPTION(status)) {
1205 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001206 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001207 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001208 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001209 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001210}
Victor Stinner6c785c02018-08-01 17:56:14 +02001211
Victor Stinner4fffd382019-03-06 01:44:31 +01001212
Victor Stinner6c785c02018-08-01 17:56:14 +02001213static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001214config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001215{
Victor Stinner74f65682019-03-15 15:08:05 +01001216 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001217}
1218
1219
Victor Stinner331a6a52019-05-27 16:39:22 +02001220static PyStatus
1221config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001222{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001223 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001224
1225 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001226 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001227 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001228 PyStatus status = PyConfig_SetString(config, &config->home, home);
1229 if (_PyStatus_EXCEPTION(status)) {
1230 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001231 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001232 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001233 }
1234
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001235 return CONFIG_GET_ENV_DUP(config, &config->home,
1236 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001237}
1238
1239
Victor Stinner331a6a52019-05-27 16:39:22 +02001240static PyStatus
1241config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001242{
Victor Stinner331a6a52019-05-27 16:39:22 +02001243 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001244
1245 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1246 /* Convert a text seed to a numeric one */
1247 if (seed_text && strcmp(seed_text, "random") != 0) {
1248 const char *endptr = seed_text;
1249 unsigned long seed;
1250 errno = 0;
1251 seed = strtoul(seed_text, (char **)&endptr, 10);
1252 if (*endptr != '\0'
1253 || seed > 4294967295UL
1254 || (errno == ERANGE && seed == ULONG_MAX))
1255 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001256 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001257 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001258 }
1259 /* Use a specific hash */
1260 config->use_hash_seed = 1;
1261 config->hash_seed = seed;
1262 }
1263 else {
1264 /* Use a random hash */
1265 config->use_hash_seed = 0;
1266 config->hash_seed = 0;
1267 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001268 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001269}
1270
1271
Victor Stinner6c785c02018-08-01 17:56:14 +02001272static int
1273config_wstr_to_int(const wchar_t *wstr, int *result)
1274{
1275 const wchar_t *endptr = wstr;
1276 errno = 0;
1277 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1278 if (*endptr != '\0' || errno == ERANGE) {
1279 return -1;
1280 }
1281 if (value < INT_MIN || value > INT_MAX) {
1282 return -1;
1283 }
1284
1285 *result = (int)value;
1286 return 0;
1287}
1288
1289
Victor Stinner331a6a52019-05-27 16:39:22 +02001290static PyStatus
1291config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001292{
Victor Stinner331a6a52019-05-27 16:39:22 +02001293 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001294 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001295
Victor Stinner6c785c02018-08-01 17:56:14 +02001296 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001297 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1298 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1299 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1300 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001301
1302 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001303 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001304 if (dont_write_bytecode) {
1305 config->write_bytecode = 0;
1306 }
1307
1308 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001309 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001310 if (no_user_site_directory) {
1311 config->user_site_directory = 0;
1312 }
1313
1314 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001315 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001316 if (unbuffered_stdio) {
1317 config->buffered_stdio = 0;
1318 }
1319
1320#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001321 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinnere662c392020-11-01 23:07:23 +01001322 "PYTHONLEGACYWINDOWSSTDIO");
Victor Stinner6c785c02018-08-01 17:56:14 +02001323#endif
1324
Victor Stinner331a6a52019-05-27 16:39:22 +02001325 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001326 config->dump_refs = 1;
1327 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001328 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001329 config->malloc_stats = 1;
1330 }
1331
Victor Stinner331a6a52019-05-27 16:39:22 +02001332 if (config->pythonpath_env == NULL) {
1333 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1334 L"PYTHONPATH", "PYTHONPATH");
1335 if (_PyStatus_EXCEPTION(status)) {
1336 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001337 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001338 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001339
Sandro Mani8f023a22020-06-08 17:28:11 +02001340 if(config->platlibdir == NULL) {
1341 status = CONFIG_GET_ENV_DUP(config, &config->platlibdir,
1342 L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR");
1343 if (_PyStatus_EXCEPTION(status)) {
1344 return status;
1345 }
1346 }
1347
Victor Stinner6c785c02018-08-01 17:56:14 +02001348 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001349 status = config_init_hash_seed(config);
1350 if (_PyStatus_EXCEPTION(status)) {
1351 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001352 }
1353 }
1354
Victor Stinner331a6a52019-05-27 16:39:22 +02001355 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001356}
1357
1358
Victor Stinner331a6a52019-05-27 16:39:22 +02001359static PyStatus
1360config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001361{
1362 int nframe;
1363 int valid;
1364
Victor Stinner331a6a52019-05-27 16:39:22 +02001365 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001366 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001367 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001368 valid = (nframe >= 0);
1369 }
1370 else {
1371 valid = 0;
1372 }
1373 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001374 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001375 }
1376 config->tracemalloc = nframe;
1377 }
1378
1379 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1380 if (xoption) {
1381 const wchar_t *sep = wcschr(xoption, L'=');
1382 if (sep) {
1383 if (!config_wstr_to_int(sep + 1, &nframe)) {
1384 valid = (nframe >= 0);
1385 }
1386 else {
1387 valid = 0;
1388 }
1389 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001390 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1391 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001392 }
1393 }
1394 else {
1395 /* -X tracemalloc behaves as -X tracemalloc=1 */
1396 nframe = 1;
1397 }
1398 config->tracemalloc = nframe;
1399 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001400 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001401}
1402
1403
Victor Stinner331a6a52019-05-27 16:39:22 +02001404static PyStatus
1405config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001406{
1407 assert(config->pycache_prefix == NULL);
1408
1409 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1410 if (xoption) {
1411 const wchar_t *sep = wcschr(xoption, L'=');
1412 if (sep && wcslen(sep) > 1) {
1413 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1414 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001415 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001416 }
1417 }
1418 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001419 // PYTHONPYCACHEPREFIX env var ignored
1420 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001421 config->pycache_prefix = NULL;
1422 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001423 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001424 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001425
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001426 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1427 L"PYTHONPYCACHEPREFIX",
1428 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001429}
1430
1431
Victor Stinner331a6a52019-05-27 16:39:22 +02001432static PyStatus
1433config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001434{
1435 /* More complex options configured by env var and -X option */
1436 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001437 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001438 || config_get_xoption(config, L"faulthandler")) {
1439 config->faulthandler = 1;
1440 }
1441 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001442 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001443 || config_get_xoption(config, L"importtime")) {
1444 config->import_time = 1;
1445 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001446
Victor Stinner331a6a52019-05-27 16:39:22 +02001447 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001448 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001449 status = config_init_tracemalloc(config);
1450 if (_PyStatus_EXCEPTION(status)) {
1451 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001452 }
1453 }
1454
1455 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001456 status = config_init_pycache_prefix(config);
1457 if (_PyStatus_EXCEPTION(status)) {
1458 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001459 }
1460 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001461 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001462}
1463
1464
Victor Stinner709d23d2019-05-02 14:56:30 -04001465static const wchar_t *
Victor Stinner710e8262020-10-31 01:02:09 +01001466config_get_stdio_errors(const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001467{
Victor Stinner710e8262020-10-31 01:02:09 +01001468 if (preconfig->utf8_mode) {
1469 /* UTF-8 Mode uses UTF-8/surrogateescape */
1470 return L"surrogateescape";
1471 }
1472
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001473#ifndef MS_WINDOWS
1474 const char *loc = setlocale(LC_CTYPE, NULL);
1475 if (loc != NULL) {
1476 /* surrogateescape is the default in the legacy C and POSIX locales */
1477 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001478 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001479 }
1480
1481#ifdef PY_COERCE_C_LOCALE
1482 /* surrogateescape is the default in locale coercion target locales */
1483 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001484 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001485 }
1486#endif
1487 }
1488
Victor Stinner709d23d2019-05-02 14:56:30 -04001489 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001490#else
1491 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001492 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001493#endif
1494}
1495
1496
Victor Stinner82458b62020-11-01 20:59:35 +01001497// See also config_get_fs_encoding()
Victor Stinner331a6a52019-05-27 16:39:22 +02001498static PyStatus
Victor Stinner710e8262020-10-31 01:02:09 +01001499config_get_locale_encoding(PyConfig *config, const PyPreConfig *preconfig,
1500 wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001501{
Victor Stinnere662c392020-11-01 23:07:23 +01001502 wchar_t *encoding = _Py_GetLocaleEncoding();
Victor Stinner82458b62020-11-01 20:59:35 +01001503 if (encoding == NULL) {
Victor Stinnere662c392020-11-01 23:07:23 +01001504 return _PyStatus_NO_MEMORY();
Victor Stinner710e8262020-10-31 01:02:09 +01001505 }
Victor Stinner82458b62020-11-01 20:59:35 +01001506 PyStatus status = PyConfig_SetString(config, locale_encoding, encoding);
1507 PyMem_RawFree(encoding);
1508 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001509}
1510
1511
Victor Stinner331a6a52019-05-27 16:39:22 +02001512static PyStatus
1513config_init_stdio_encoding(PyConfig *config,
1514 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001515{
Victor Stinner331a6a52019-05-27 16:39:22 +02001516 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001517
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001518 /* If Py_SetStandardStreamEncoding() have been called, use these
1519 parameters. */
1520 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001521 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1522 _Py_StandardStreamEncoding,
1523 "_Py_StandardStreamEncoding");
1524 if (_PyStatus_EXCEPTION(status)) {
1525 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001526 }
1527 }
1528
1529 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001530 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1531 _Py_StandardStreamErrors,
1532 "_Py_StandardStreamErrors");
1533 if (_PyStatus_EXCEPTION(status)) {
1534 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001535 }
1536 }
1537
1538 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001539 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001540 }
1541
1542 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001543 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001544 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001545 char *pythonioencoding = _PyMem_RawStrdup(opt);
1546 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001547 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001548 }
1549
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001550 char *errors = strchr(pythonioencoding, ':');
1551 if (errors) {
1552 *errors = '\0';
1553 errors++;
1554 if (!errors[0]) {
1555 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001556 }
1557 }
1558
1559 /* Does PYTHONIOENCODING contain an encoding? */
1560 if (pythonioencoding[0]) {
1561 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001562 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1563 pythonioencoding,
1564 "PYTHONIOENCODING environment variable");
1565 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001566 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001567 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001568 }
1569 }
1570
1571 /* If the encoding is set but not the error handler,
1572 use "strict" error handler by default.
1573 PYTHONIOENCODING=latin1 behaves as
1574 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001575 if (!errors) {
1576 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001577 }
1578 }
1579
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001580 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001581 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1582 errors,
1583 "PYTHONIOENCODING environment variable");
1584 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001585 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001586 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001587 }
1588 }
1589
1590 PyMem_RawFree(pythonioencoding);
1591 }
1592
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001593 /* Choose the default error handler based on the current locale. */
1594 if (config->stdio_encoding == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001595 status = config_get_locale_encoding(config, preconfig,
1596 &config->stdio_encoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001597 if (_PyStatus_EXCEPTION(status)) {
1598 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001599 }
1600 }
1601 if (config->stdio_errors == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001602 const wchar_t *errors = config_get_stdio_errors(preconfig);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001603 assert(errors != NULL);
1604
Victor Stinner331a6a52019-05-27 16:39:22 +02001605 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1606 if (_PyStatus_EXCEPTION(status)) {
1607 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001608 }
1609 }
1610
Victor Stinner331a6a52019-05-27 16:39:22 +02001611 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001612}
1613
1614
Victor Stinner710e8262020-10-31 01:02:09 +01001615// See also config_get_locale_encoding()
1616static PyStatus
1617config_get_fs_encoding(PyConfig *config, const PyPreConfig *preconfig,
1618 wchar_t **fs_encoding)
1619{
1620#ifdef _Py_FORCE_UTF8_FS_ENCODING
1621 return PyConfig_SetString(config, fs_encoding, L"utf-8");
1622#elif defined(MS_WINDOWS)
1623 const wchar_t *encoding;
1624 if (preconfig->legacy_windows_fs_encoding) {
1625 // Legacy Windows filesystem encoding: mbcs/replace
1626 encoding = L"mbcs";
1627 }
1628 else {
1629 // Windows defaults to utf-8/surrogatepass (PEP 529)
1630 encoding = L"utf-8";
1631 }
1632 return PyConfig_SetString(config, fs_encoding, encoding);
1633#else // !MS_WINDOWS
1634 if (preconfig->utf8_mode) {
1635 return PyConfig_SetString(config, fs_encoding, L"utf-8");
1636 }
1637 else if (_Py_GetForceASCII()) {
1638 return PyConfig_SetString(config, fs_encoding, L"ascii");
1639 }
1640 else {
1641 return config_get_locale_encoding(config, preconfig, fs_encoding);
1642 }
1643#endif // !MS_WINDOWS
1644}
1645
1646
Victor Stinner331a6a52019-05-27 16:39:22 +02001647static PyStatus
1648config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001649{
Victor Stinner331a6a52019-05-27 16:39:22 +02001650 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001651
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001652 if (config->filesystem_encoding == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001653 status = config_get_fs_encoding(config, preconfig,
1654 &config->filesystem_encoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001655 if (_PyStatus_EXCEPTION(status)) {
1656 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001657 }
1658 }
1659
1660 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001661 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001662#ifdef MS_WINDOWS
1663 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001664 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001665 }
1666 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001667 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001668 }
1669#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001670 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001671#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001672 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1673 if (_PyStatus_EXCEPTION(status)) {
1674 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001675 }
1676 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001677 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001678}
1679
1680
Victor Stinner331a6a52019-05-27 16:39:22 +02001681static PyStatus
1682config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001683{
Victor Stinner331a6a52019-05-27 16:39:22 +02001684 PyStatus status;
1685 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001686
Victor Stinner20004952019-03-26 02:31:11 +01001687 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001688 status = config_read_env_vars(config);
1689 if (_PyStatus_EXCEPTION(status)) {
1690 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001691 }
1692 }
1693
1694 /* -X options */
1695 if (config_get_xoption(config, L"showrefcount")) {
1696 config->show_ref_count = 1;
1697 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001698
Victor Stinner331a6a52019-05-27 16:39:22 +02001699 status = config_read_complex_options(config);
1700 if (_PyStatus_EXCEPTION(status)) {
1701 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001702 }
1703
Victor Stinner6c785c02018-08-01 17:56:14 +02001704 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001705 status = config_init_home(config);
1706 if (_PyStatus_EXCEPTION(status)) {
1707 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001708 }
1709 }
1710
Steve Dower177a41a2018-11-17 20:41:48 -08001711 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001712 status = config_init_executable(config);
1713 if (_PyStatus_EXCEPTION(status)) {
1714 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001715 }
1716 }
1717
Sandro Mani8f023a22020-06-08 17:28:11 +02001718 if(config->platlibdir == NULL) {
1719 status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR,
1720 "PLATLIBDIR macro");
1721 if (_PyStatus_EXCEPTION(status)) {
1722 return status;
1723 }
1724 }
1725
Victor Stinner6c785c02018-08-01 17:56:14 +02001726 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001727 status = _PyConfig_InitPathConfig(config);
1728 if (_PyStatus_EXCEPTION(status)) {
1729 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001730 }
1731 }
1732
1733 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001734 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001735 if (config->faulthandler < 0) {
1736 config->faulthandler = 1;
1737 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001738 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001739 if (config->faulthandler < 0) {
1740 config->faulthandler = 0;
1741 }
1742 if (config->tracemalloc < 0) {
1743 config->tracemalloc = 0;
1744 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001745 if (config->use_hash_seed < 0) {
1746 config->use_hash_seed = 0;
1747 config->hash_seed = 0;
1748 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001749
Victor Stinner70fead22018-08-29 13:45:34 +02001750 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001751 status = config_init_fs_encoding(config, preconfig);
1752 if (_PyStatus_EXCEPTION(status)) {
1753 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001754 }
1755 }
1756
Victor Stinner331a6a52019-05-27 16:39:22 +02001757 status = config_init_stdio_encoding(config, preconfig);
1758 if (_PyStatus_EXCEPTION(status)) {
1759 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001760 }
1761
Victor Stinner62599762019-03-15 16:03:23 +01001762 if (config->argv.length < 1) {
1763 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001764 status = PyWideStringList_Append(&config->argv, L"");
1765 if (_PyStatus_EXCEPTION(status)) {
1766 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001767 }
1768 }
Victor Stinner870b0352019-05-17 03:15:12 +02001769
1770 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001771 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1772 L"default");
1773 if (_PyStatus_EXCEPTION(status)) {
1774 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001775 }
1776 }
1777
1778 if (config->configure_c_stdio < 0) {
1779 config->configure_c_stdio = 1;
1780 }
1781
Victor Stinner331a6a52019-05-27 16:39:22 +02001782 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001783}
Victor Stinner5ed69952018-11-06 15:59:52 +01001784
1785
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001786static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001787config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001788{
1789#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1790 /* don't translate newlines (\r\n <=> \n) */
1791 _setmode(fileno(stdin), O_BINARY);
1792 _setmode(fileno(stdout), O_BINARY);
1793 _setmode(fileno(stderr), O_BINARY);
1794#endif
1795
1796 if (!config->buffered_stdio) {
1797#ifdef HAVE_SETVBUF
1798 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1799 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1800 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1801#else /* !HAVE_SETVBUF */
1802 setbuf(stdin, (char *)NULL);
1803 setbuf(stdout, (char *)NULL);
1804 setbuf(stderr, (char *)NULL);
1805#endif /* !HAVE_SETVBUF */
1806 }
1807 else if (config->interactive) {
1808#ifdef MS_WINDOWS
1809 /* Doesn't have to have line-buffered -- use unbuffered */
1810 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1811 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1812#else /* !MS_WINDOWS */
1813#ifdef HAVE_SETVBUF
1814 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1815 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1816#endif /* HAVE_SETVBUF */
1817#endif /* !MS_WINDOWS */
1818 /* Leave stderr alone - it should be unbuffered anyway. */
1819 }
1820}
1821
1822
1823/* Write the configuration:
1824
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001825 - set Py_xxx global configuration variables
1826 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinnere81f6e62020-06-08 18:12:59 +02001827PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +02001828_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001829{
Victor Stinner331a6a52019-05-27 16:39:22 +02001830 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001831
1832 if (config->configure_c_stdio) {
1833 config_init_stdio(config);
1834 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001835
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001836 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001837 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001838 preconfig->isolated = config->isolated;
1839 preconfig->use_environment = config->use_environment;
1840 preconfig->dev_mode = config->dev_mode;
Victor Stinnere81f6e62020-06-08 18:12:59 +02001841
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02001842 if (_Py_SetArgcArgv(config->orig_argv.length,
1843 config->orig_argv.items) < 0)
Victor Stinnere81f6e62020-06-08 18:12:59 +02001844 {
1845 return _PyStatus_NO_MEMORY();
1846 }
1847 return _PyStatus_OK();
Victor Stinner5ed69952018-11-06 15:59:52 +01001848}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001849
1850
Victor Stinner331a6a52019-05-27 16:39:22 +02001851/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001852
1853static void
Victor Stinner2f549082019-03-29 15:13:46 +01001854config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001855{
Victor Stinner2f549082019-03-29 15:13:46 +01001856 FILE *f = error ? stderr : stdout;
1857
1858 fprintf(f, usage_line, program);
1859 if (error)
1860 fprintf(f, "Try `python -h' for more information.\n");
1861 else {
1862 fputs(usage_1, f);
1863 fputs(usage_2, f);
1864 fputs(usage_3, f);
1865 fprintf(f, usage_4, (wint_t)DELIM);
1866 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1867 fputs(usage_6, f);
1868 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001869}
1870
1871
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001872/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001873static PyStatus
1874config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001875 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001876{
Victor Stinner331a6a52019-05-27 16:39:22 +02001877 PyStatus status;
1878 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001879 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001880 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001881
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001882 _PyOS_ResetGetOpt();
1883 do {
1884 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001885 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001886 if (c == EOF) {
1887 break;
1888 }
1889
1890 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001891 if (config->run_command == NULL) {
1892 /* -c is the last option; following arguments
1893 that look like options are left for the
1894 command to interpret. */
1895 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1896 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1897 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001898 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001899 }
1900 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1901 command[len - 2] = '\n';
1902 command[len - 1] = 0;
1903 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001904 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001905 break;
1906 }
1907
1908 if (c == 'm') {
1909 /* -m is the last option; following arguments
1910 that look like options are left for the
1911 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001912 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001913 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1914 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001915 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001916 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001917 }
1918 break;
1919 }
1920
1921 switch (c) {
1922 case 0:
1923 // Handle long option.
1924 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001925 if (wcscmp(_PyOS_optarg, L"always") == 0
1926 || wcscmp(_PyOS_optarg, L"never") == 0
1927 || wcscmp(_PyOS_optarg, L"default") == 0)
1928 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001929 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1930 _PyOS_optarg);
1931 if (_PyStatus_EXCEPTION(status)) {
1932 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001933 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001934 } else {
1935 fprintf(stderr, "--check-hash-based-pycs must be one of "
1936 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001937 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001938 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001939 }
1940 break;
1941
1942 case 'b':
1943 config->bytes_warning++;
1944 break;
1945
1946 case 'd':
1947 config->parser_debug++;
1948 break;
1949
1950 case 'i':
1951 config->inspect++;
1952 config->interactive++;
1953 break;
1954
Victor Stinner6dcb5422019-03-05 02:44:12 +01001955 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001956 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001957 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001958 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001959 break;
1960
1961 /* case 'J': reserved for Jython */
1962
1963 case 'O':
1964 config->optimization_level++;
1965 break;
1966
1967 case 'B':
1968 config->write_bytecode = 0;
1969 break;
1970
1971 case 's':
1972 config->user_site_directory = 0;
1973 break;
1974
1975 case 'S':
1976 config->site_import = 0;
1977 break;
1978
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001979 case 't':
1980 /* ignored for backwards compatibility */
1981 break;
1982
1983 case 'u':
1984 config->buffered_stdio = 0;
1985 break;
1986
1987 case 'v':
1988 config->verbose++;
1989 break;
1990
1991 case 'x':
1992 config->skip_source_first_line = 1;
1993 break;
1994
1995 case 'h':
1996 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001997 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001998 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001999
2000 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01002001 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002002 break;
2003
2004 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002005 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2006 if (_PyStatus_EXCEPTION(status)) {
2007 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002008 }
2009 break;
2010
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002011 case 'q':
2012 config->quiet++;
2013 break;
2014
2015 case 'R':
2016 config->use_hash_seed = 0;
2017 break;
2018
2019 /* This space reserved for other options */
2020
2021 default:
2022 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002023 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002024 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002025 }
2026 } while (1);
2027
Victor Stinner2f549082019-03-29 15:13:46 +01002028 if (print_version) {
2029 printf("Python %s\n",
2030 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002031 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002032 }
2033
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002034 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002035 && _PyOS_optind < argv->length
2036 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002037 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002038 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002039 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002040 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002041 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002042 }
2043 }
2044
2045 if (config->run_command != NULL || config->run_module != NULL) {
2046 /* Backup _PyOS_optind */
2047 _PyOS_optind--;
2048 }
2049
Victor Stinnerae239f62019-05-16 17:02:56 +02002050 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002051
Victor Stinner331a6a52019-05-27 16:39:22 +02002052 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002053}
2054
2055
2056#ifdef MS_WINDOWS
2057# define WCSTOK wcstok_s
2058#else
2059# define WCSTOK wcstok
2060#endif
2061
2062/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002063static PyStatus
2064config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002065{
Victor Stinner331a6a52019-05-27 16:39:22 +02002066 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002067 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2068 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002069 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002070 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002071 if (_PyStatus_EXCEPTION(status)) {
2072 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002073 }
2074
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002075 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002076 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002077 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002078 }
2079
2080
2081 wchar_t *warning, *context = NULL;
2082 for (warning = WCSTOK(env, L",", &context);
2083 warning != NULL;
2084 warning = WCSTOK(NULL, L",", &context))
2085 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002086 status = PyWideStringList_Append(warnoptions, warning);
2087 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002088 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002089 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002090 }
2091 }
2092 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002093 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002094}
2095
2096
Victor Stinner331a6a52019-05-27 16:39:22 +02002097static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002098warnoptions_append(PyConfig *config, PyWideStringList *options,
2099 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002100{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002101 /* config_init_warnoptions() add existing config warnoptions at the end:
2102 ensure that the new option is not already present in this list to
2103 prevent change the options order whne config_init_warnoptions() is
2104 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002105 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002106 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002107 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002108 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002109 if (_PyWideStringList_Find(options, option)) {
2110 /* Already present: do nothing */
2111 return _PyStatus_OK();
2112 }
2113 return PyWideStringList_Append(options, option);
2114}
2115
2116
2117static PyStatus
2118warnoptions_extend(PyConfig *config, PyWideStringList *options,
2119 const PyWideStringList *options2)
2120{
2121 const Py_ssize_t len = options2->length;
2122 wchar_t *const *items = options2->items;
2123
2124 for (Py_ssize_t i = 0; i < len; i++) {
2125 PyStatus status = warnoptions_append(config, options, items[i]);
2126 if (_PyStatus_EXCEPTION(status)) {
2127 return status;
2128 }
2129 }
2130 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002131}
2132
2133
Victor Stinner331a6a52019-05-27 16:39:22 +02002134static PyStatus
2135config_init_warnoptions(PyConfig *config,
2136 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002137 const PyWideStringList *env_warnoptions,
2138 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002139{
Victor Stinner331a6a52019-05-27 16:39:22 +02002140 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002141 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002142
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002143 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002144 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002145 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002146 * - PyConfig.dev_mode: "default" filter
2147 * - PYTHONWARNINGS environment variable
2148 * - '-W' command line options
2149 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2150 * "default::BytesWarning" or "error::BytesWarning" filter
2151 * - early PySys_AddWarnOption() calls
2152 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002153 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002154 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2155 * module works on the basis of "the most recently added filter will be
2156 * checked first", we add the lowest precedence entries first so that later
2157 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002158 */
2159
Victor Stinner20004952019-03-26 02:31:11 +01002160 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002161 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002162 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002163 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002164 }
2165 }
2166
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002167 status = warnoptions_extend(config, &options, env_warnoptions);
2168 if (_PyStatus_EXCEPTION(status)) {
2169 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002170 }
2171
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002172 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2173 if (_PyStatus_EXCEPTION(status)) {
2174 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002175 }
2176
2177 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2178 * don't even try to emit a warning, so we skip setting the filter in that
2179 * case.
2180 */
2181 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002182 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002183 if (config->bytes_warning> 1) {
2184 filter = L"error::BytesWarning";
2185 }
2186 else {
2187 filter = L"default::BytesWarning";
2188 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002189 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002190 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002191 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002192 }
2193 }
Victor Stinner120b7072019-08-23 18:03:08 +01002194
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002195 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002196 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002197 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002198 }
2199
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002200 /* Always add all PyConfig.warnoptions options */
2201 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2202 if (_PyStatus_EXCEPTION(status)) {
2203 goto error;
2204 }
2205
2206 _PyWideStringList_Clear(&config->warnoptions);
2207 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002208 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002209
2210error:
2211 _PyWideStringList_Clear(&options);
2212 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002213}
2214
2215
Victor Stinner331a6a52019-05-27 16:39:22 +02002216static PyStatus
2217config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002218{
Victor Stinner331a6a52019-05-27 16:39:22 +02002219 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002220 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002221
Victor Stinner74f65682019-03-15 15:08:05 +01002222 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002223 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002224 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002225 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2226 if (_PyStatus_EXCEPTION(status)) {
2227 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002228 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002229 }
2230 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002231 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002232 slice.length = cmdline_argv->length - opt_index;
2233 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002234 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2235 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002236 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002237 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002238 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002239
2240 wchar_t *arg0 = NULL;
2241 if (config->run_command != NULL) {
2242 /* Force sys.argv[0] = '-c' */
2243 arg0 = L"-c";
2244 }
2245 else if (config->run_module != NULL) {
2246 /* Force sys.argv[0] = '-m'*/
2247 arg0 = L"-m";
2248 }
Victor Stinner3939c322019-06-25 15:02:43 +02002249
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002250 if (arg0 != NULL) {
2251 arg0 = _PyMem_RawWcsdup(arg0);
2252 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002253 _PyWideStringList_Clear(&config_argv);
2254 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002255 }
2256
Victor Stinnerfa153762019-03-20 04:25:38 +01002257 PyMem_RawFree(config_argv.items[0]);
2258 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002259 }
2260
Victor Stinner331a6a52019-05-27 16:39:22 +02002261 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002262 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002263 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002264}
2265
2266
Victor Stinner331a6a52019-05-27 16:39:22 +02002267static PyStatus
2268core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002269{
Victor Stinner331a6a52019-05-27 16:39:22 +02002270 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002271
Victor Stinnercab5d072019-05-17 19:01:14 +02002272 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002273 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2274 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002275 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002276 }
2277
Victor Stinner331a6a52019-05-27 16:39:22 +02002278 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002279
2280 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2281 if (_PyStatus_EXCEPTION(status)) {
2282 return status;
2283 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002284
Victor Stinner331a6a52019-05-27 16:39:22 +02002285 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002286
Victor Stinner331a6a52019-05-27 16:39:22 +02002287 status = _PyPreCmdline_Read(precmdline, &preconfig);
2288 if (_PyStatus_EXCEPTION(status)) {
2289 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002290 }
2291
Victor Stinner331a6a52019-05-27 16:39:22 +02002292 status = _PyPreCmdline_SetConfig(precmdline, config);
2293 if (_PyStatus_EXCEPTION(status)) {
2294 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002295 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002296 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002297}
2298
2299
Victor Stinner3939c322019-06-25 15:02:43 +02002300/* Get run_filename absolute path */
2301static PyStatus
2302config_run_filename_abspath(PyConfig *config)
2303{
2304 if (!config->run_filename) {
2305 return _PyStatus_OK();
2306 }
2307
2308#ifndef MS_WINDOWS
2309 if (_Py_isabs(config->run_filename)) {
2310 /* path is already absolute */
2311 return _PyStatus_OK();
2312 }
2313#endif
2314
2315 wchar_t *abs_filename;
2316 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2317 /* failed to get the absolute path of the command line filename:
2318 ignore the error, keep the relative path */
2319 return _PyStatus_OK();
2320 }
2321 if (abs_filename == NULL) {
2322 return _PyStatus_NO_MEMORY();
2323 }
2324
2325 PyMem_RawFree(config->run_filename);
2326 config->run_filename = abs_filename;
2327 return _PyStatus_OK();
2328}
2329
2330
Victor Stinner331a6a52019-05-27 16:39:22 +02002331static PyStatus
2332config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002333{
Victor Stinner331a6a52019-05-27 16:39:22 +02002334 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002335 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2336 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2337 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002338
Victor Stinnerae239f62019-05-16 17:02:56 +02002339 if (config->parse_argv < 0) {
2340 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002341 }
Victor Stinner870b0352019-05-17 03:15:12 +02002342
Victor Stinnerfed02e12019-05-17 11:12:09 +02002343 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002344 status = config_init_program_name(config);
2345 if (_PyStatus_EXCEPTION(status)) {
2346 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002347 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002348 }
Victor Stinner2f549082019-03-29 15:13:46 +01002349
Victor Stinnerae239f62019-05-16 17:02:56 +02002350 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002351 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002352 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2353 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002354 goto done;
2355 }
2356
Victor Stinner3939c322019-06-25 15:02:43 +02002357 status = config_run_filename_abspath(config);
2358 if (_PyStatus_EXCEPTION(status)) {
2359 goto done;
2360 }
2361
Victor Stinner331a6a52019-05-27 16:39:22 +02002362 status = config_update_argv(config, opt_index);
2363 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002364 goto done;
2365 }
Victor Stinner2f549082019-03-29 15:13:46 +01002366 }
Victor Stinner3939c322019-06-25 15:02:43 +02002367 else {
2368 status = config_run_filename_abspath(config);
2369 if (_PyStatus_EXCEPTION(status)) {
2370 goto done;
2371 }
2372 }
Victor Stinner2f549082019-03-29 15:13:46 +01002373
Victor Stinner2f549082019-03-29 15:13:46 +01002374 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002375 status = config_init_env_warnoptions(config, &env_warnoptions);
2376 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002377 goto done;
2378 }
2379 }
2380
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002381 /* Handle early PySys_AddWarnOption() calls */
2382 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2383 if (_PyStatus_EXCEPTION(status)) {
2384 goto done;
2385 }
2386
Victor Stinner331a6a52019-05-27 16:39:22 +02002387 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002388 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002389 &env_warnoptions,
2390 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002391 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002392 goto done;
2393 }
2394
Victor Stinner331a6a52019-05-27 16:39:22 +02002395 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002396
2397done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002398 _PyWideStringList_Clear(&cmdline_warnoptions);
2399 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002400 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002401 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002402}
2403
2404
Victor Stinner331a6a52019-05-27 16:39:22 +02002405PyStatus
2406_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002407{
Victor Stinner331a6a52019-05-27 16:39:22 +02002408 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2409 if (_PyStatus_EXCEPTION(status)) {
2410 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002411 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002412
Victor Stinner5f38b842019-05-01 02:30:12 +02002413 return _PyArgv_AsWstrList(args, &config->argv);
2414}
2415
2416
Victor Stinner70005ac2019-05-02 15:25:34 -04002417/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2418 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002419PyStatus
2420PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002421{
2422 _PyArgv args = {
2423 .argc = argc,
2424 .use_bytes_argv = 1,
2425 .bytes_argv = argv,
2426 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002427 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002428}
2429
2430
Victor Stinner331a6a52019-05-27 16:39:22 +02002431PyStatus
2432PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002433{
2434 _PyArgv args = {
2435 .argc = argc,
2436 .use_bytes_argv = 0,
2437 .bytes_argv = NULL,
2438 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002439 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002440}
2441
2442
Victor Stinner36242fd2019-07-01 19:13:50 +02002443PyStatus
2444PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2445 Py_ssize_t length, wchar_t **items)
2446{
2447 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2448 if (_PyStatus_EXCEPTION(status)) {
2449 return status;
2450 }
2451
2452 PyWideStringList list2 = {.length = length, .items = items};
2453 if (_PyWideStringList_Copy(list, &list2) < 0) {
2454 return _PyStatus_NO_MEMORY();
2455 }
2456 return _PyStatus_OK();
2457}
2458
2459
Victor Stinner331a6a52019-05-27 16:39:22 +02002460/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002461
2462 * Command line arguments
2463 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002464 * Py_xxx global configuration variables
2465
2466 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002467PyStatus
2468PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002469{
Victor Stinner331a6a52019-05-27 16:39:22 +02002470 PyStatus status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002471
Victor Stinner331a6a52019-05-27 16:39:22 +02002472 status = _Py_PreInitializeFromConfig(config, NULL);
2473 if (_PyStatus_EXCEPTION(status)) {
2474 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002475 }
2476
Victor Stinner331a6a52019-05-27 16:39:22 +02002477 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002478
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002479 if (config->orig_argv.length == 0
Victor Stinnere81f6e62020-06-08 18:12:59 +02002480 && !(config->argv.length == 1
2481 && wcscmp(config->argv.items[0], L"") == 0))
2482 {
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002483 if (_PyWideStringList_Copy(&config->orig_argv, &config->argv) < 0) {
Victor Stinnere81f6e62020-06-08 18:12:59 +02002484 return _PyStatus_NO_MEMORY();
2485 }
Victor Stinnercab5d072019-05-17 19:01:14 +02002486 }
2487
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002488 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002489 status = core_read_precmdline(config, &precmdline);
2490 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002491 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002492 }
2493
Victor Stinner870b0352019-05-17 03:15:12 +02002494 assert(config->isolated >= 0);
2495 if (config->isolated) {
2496 config->use_environment = 0;
2497 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002498 }
2499
Victor Stinner331a6a52019-05-27 16:39:22 +02002500 status = config_read_cmdline(config);
2501 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002502 goto done;
2503 }
2504
Victor Stinner120b7072019-08-23 18:03:08 +01002505 /* Handle early PySys_AddXOption() calls */
2506 status = _PySys_ReadPreinitXOptions(config);
2507 if (_PyStatus_EXCEPTION(status)) {
2508 goto done;
2509 }
2510
Victor Stinner331a6a52019-05-27 16:39:22 +02002511 status = config_read(config);
2512 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002513 goto done;
2514 }
2515
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002516 /* Check config consistency */
2517 assert(config->isolated >= 0);
2518 assert(config->use_environment >= 0);
2519 assert(config->dev_mode >= 0);
2520 assert(config->install_signal_handlers >= 0);
2521 assert(config->use_hash_seed >= 0);
2522 assert(config->faulthandler >= 0);
2523 assert(config->tracemalloc >= 0);
2524 assert(config->site_import >= 0);
2525 assert(config->bytes_warning >= 0);
2526 assert(config->inspect >= 0);
2527 assert(config->interactive >= 0);
2528 assert(config->optimization_level >= 0);
2529 assert(config->parser_debug >= 0);
2530 assert(config->write_bytecode >= 0);
2531 assert(config->verbose >= 0);
2532 assert(config->quiet >= 0);
2533 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002534 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002535 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002536 assert(config->buffered_stdio >= 0);
2537 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002538 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002539 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2540 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002541 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2542 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2543 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002544 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002545 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002546 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002547 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002548 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002549 assert(config->prefix != NULL);
2550 assert(config->base_prefix != NULL);
2551 assert(config->exec_prefix != NULL);
2552 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002553 }
Sandro Mani8f023a22020-06-08 17:28:11 +02002554 assert(config->platlibdir != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002555 assert(config->filesystem_encoding != NULL);
2556 assert(config->filesystem_errors != NULL);
2557 assert(config->stdio_encoding != NULL);
2558 assert(config->stdio_errors != NULL);
2559#ifdef MS_WINDOWS
2560 assert(config->legacy_windows_stdio >= 0);
2561#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002562 /* -c and -m options are exclusive */
2563 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002564 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002565 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002566 assert(config->pathconfig_warnings >= 0);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002567 assert(_PyWideStringList_CheckConsistency(&config->orig_argv));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002568
Victor Stinner331a6a52019-05-27 16:39:22 +02002569 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002570
2571done:
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002572 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002573 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002574}
Victor Stinner1075d162019-03-25 23:19:57 +01002575
2576
2577PyObject*
2578_Py_GetConfigsAsDict(void)
2579{
Victor Stinner331a6a52019-05-27 16:39:22 +02002580 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002581 PyObject *dict = NULL;
2582
Victor Stinner331a6a52019-05-27 16:39:22 +02002583 result = PyDict_New();
2584 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002585 goto error;
2586 }
2587
Victor Stinner331a6a52019-05-27 16:39:22 +02002588 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002589 dict = _Py_GetGlobalVariablesAsDict();
2590 if (dict == NULL) {
2591 goto error;
2592 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002593 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002594 goto error;
2595 }
2596 Py_CLEAR(dict);
2597
2598 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002599 PyThreadState *tstate = _PyThreadState_GET();
2600 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002601 dict = _PyPreConfig_AsDict(pre_config);
2602 if (dict == NULL) {
2603 goto error;
2604 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002605 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002606 goto error;
2607 }
2608 Py_CLEAR(dict);
2609
2610 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002611 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinner331a6a52019-05-27 16:39:22 +02002612 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002613 if (dict == NULL) {
2614 goto error;
2615 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002616 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002617 goto error;
2618 }
2619 Py_CLEAR(dict);
2620
Victor Stinner8f427482020-07-08 00:20:37 +02002621 /* path config */
2622 dict = _PyPathConfig_AsDict();
2623 if (dict == NULL) {
2624 goto error;
2625 }
2626 if (PyDict_SetItemString(result, "path_config", dict) < 0) {
2627 goto error;
2628 }
2629 Py_CLEAR(dict);
2630
Victor Stinner331a6a52019-05-27 16:39:22 +02002631 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002632
2633error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002634 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002635 Py_XDECREF(dict);
2636 return NULL;
2637}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002638
2639
2640static void
2641init_dump_ascii_wstr(const wchar_t *str)
2642{
2643 if (str == NULL) {
2644 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002645 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002646 }
2647
2648 PySys_WriteStderr("'");
2649 for (; *str != L'\0'; str++) {
Victor Stinner640e8e12020-09-09 12:07:17 +02002650 unsigned int ch = (unsigned int)*str;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002651 if (ch == L'\'') {
2652 PySys_WriteStderr("\\'");
2653 } else if (0x20 <= ch && ch < 0x7f) {
Samuel Marksc3229482020-09-21 18:35:17 +10002654 PySys_WriteStderr("%c", ch);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002655 }
2656 else if (ch <= 0xff) {
2657 PySys_WriteStderr("\\x%02x", ch);
2658 }
2659#if SIZEOF_WCHAR_T > 2
2660 else if (ch > 0xffff) {
2661 PySys_WriteStderr("\\U%08x", ch);
2662 }
2663#endif
2664 else {
2665 PySys_WriteStderr("\\u%04x", ch);
2666 }
2667 }
2668 PySys_WriteStderr("'");
2669}
2670
2671
2672/* Dump the Python path configuration into sys.stderr */
2673void
2674_Py_DumpPathConfig(PyThreadState *tstate)
2675{
2676 PyObject *exc_type, *exc_value, *exc_tb;
2677 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2678
2679 PySys_WriteStderr("Python path configuration:\n");
2680
2681#define DUMP_CONFIG(NAME, FIELD) \
2682 do { \
2683 PySys_WriteStderr(" " NAME " = "); \
2684 init_dump_ascii_wstr(config->FIELD); \
2685 PySys_WriteStderr("\n"); \
2686 } while (0)
2687
Victor Stinnerda7933e2020-04-13 03:04:28 +02002688 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002689 DUMP_CONFIG("PYTHONHOME", home);
2690 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2691 DUMP_CONFIG("program name", program_name);
2692 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2693 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2694 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2695 PySys_WriteStderr(" import site = %i\n", config->site_import);
2696#undef DUMP_CONFIG
2697
2698#define DUMP_SYS(NAME) \
2699 do { \
2700 obj = PySys_GetObject(#NAME); \
2701 PySys_FormatStderr(" sys.%s = ", #NAME); \
2702 if (obj != NULL) { \
2703 PySys_FormatStderr("%A", obj); \
2704 } \
2705 else { \
2706 PySys_WriteStderr("(not set)"); \
2707 } \
2708 PySys_FormatStderr("\n"); \
2709 } while (0)
2710
2711 PyObject *obj;
2712 DUMP_SYS(_base_executable);
2713 DUMP_SYS(base_prefix);
2714 DUMP_SYS(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +02002715 DUMP_SYS(platlibdir);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002716 DUMP_SYS(executable);
2717 DUMP_SYS(prefix);
2718 DUMP_SYS(exec_prefix);
2719#undef DUMP_SYS
2720
2721 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2722 if (sys_path != NULL && PyList_Check(sys_path)) {
2723 PySys_WriteStderr(" sys.path = [\n");
2724 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2725 for (Py_ssize_t i=0; i < len; i++) {
2726 PyObject *path = PyList_GET_ITEM(sys_path, i);
2727 PySys_FormatStderr(" %A,\n", path);
2728 }
2729 PySys_WriteStderr(" ]\n");
2730 }
2731
2732 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2733}