blob: 15fb3e4d2877dd000fbc95fd77297c760657e220 [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 Stinner35297182020-11-04 11:20:10 +01001518 /* If Py_SetStandardStreamEncoding() has been called, use its
1519 arguments if they are not NULL. */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001520 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
Victor Stinner35297182020-11-04 11:20:10 +01001538 // Exit if encoding and errors are defined
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001539 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001540 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001541 }
1542
1543 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001544 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001545 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001546 char *pythonioencoding = _PyMem_RawStrdup(opt);
1547 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001548 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001549 }
1550
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001551 char *errors = strchr(pythonioencoding, ':');
1552 if (errors) {
1553 *errors = '\0';
1554 errors++;
1555 if (!errors[0]) {
1556 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001557 }
1558 }
1559
1560 /* Does PYTHONIOENCODING contain an encoding? */
1561 if (pythonioencoding[0]) {
1562 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001563 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1564 pythonioencoding,
1565 "PYTHONIOENCODING environment variable");
1566 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001567 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001568 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001569 }
1570 }
1571
1572 /* If the encoding is set but not the error handler,
1573 use "strict" error handler by default.
1574 PYTHONIOENCODING=latin1 behaves as
1575 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001576 if (!errors) {
1577 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001578 }
1579 }
1580
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001581 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001582 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1583 errors,
1584 "PYTHONIOENCODING environment variable");
1585 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001586 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001587 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001588 }
1589 }
1590
1591 PyMem_RawFree(pythonioencoding);
1592 }
1593
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001594 /* Choose the default error handler based on the current locale. */
1595 if (config->stdio_encoding == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001596 status = config_get_locale_encoding(config, preconfig,
1597 &config->stdio_encoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001598 if (_PyStatus_EXCEPTION(status)) {
1599 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001600 }
1601 }
1602 if (config->stdio_errors == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001603 const wchar_t *errors = config_get_stdio_errors(preconfig);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001604 assert(errors != NULL);
1605
Victor Stinner331a6a52019-05-27 16:39:22 +02001606 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1607 if (_PyStatus_EXCEPTION(status)) {
1608 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001609 }
1610 }
1611
Victor Stinner331a6a52019-05-27 16:39:22 +02001612 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001613}
1614
1615
Victor Stinner710e8262020-10-31 01:02:09 +01001616// See also config_get_locale_encoding()
1617static PyStatus
1618config_get_fs_encoding(PyConfig *config, const PyPreConfig *preconfig,
1619 wchar_t **fs_encoding)
1620{
1621#ifdef _Py_FORCE_UTF8_FS_ENCODING
1622 return PyConfig_SetString(config, fs_encoding, L"utf-8");
1623#elif defined(MS_WINDOWS)
1624 const wchar_t *encoding;
1625 if (preconfig->legacy_windows_fs_encoding) {
1626 // Legacy Windows filesystem encoding: mbcs/replace
1627 encoding = L"mbcs";
1628 }
1629 else {
1630 // Windows defaults to utf-8/surrogatepass (PEP 529)
1631 encoding = L"utf-8";
1632 }
1633 return PyConfig_SetString(config, fs_encoding, encoding);
1634#else // !MS_WINDOWS
1635 if (preconfig->utf8_mode) {
1636 return PyConfig_SetString(config, fs_encoding, L"utf-8");
1637 }
Victor Stinner35297182020-11-04 11:20:10 +01001638
1639 if (_Py_GetForceASCII()) {
Victor Stinner710e8262020-10-31 01:02:09 +01001640 return PyConfig_SetString(config, fs_encoding, L"ascii");
1641 }
Victor Stinner35297182020-11-04 11:20:10 +01001642
1643 return config_get_locale_encoding(config, preconfig, fs_encoding);
Victor Stinner710e8262020-10-31 01:02:09 +01001644#endif // !MS_WINDOWS
1645}
1646
1647
Victor Stinner331a6a52019-05-27 16:39:22 +02001648static PyStatus
1649config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001650{
Victor Stinner331a6a52019-05-27 16:39:22 +02001651 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001652
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001653 if (config->filesystem_encoding == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001654 status = config_get_fs_encoding(config, preconfig,
1655 &config->filesystem_encoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001656 if (_PyStatus_EXCEPTION(status)) {
1657 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001658 }
1659 }
1660
1661 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001662 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001663#ifdef MS_WINDOWS
1664 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001665 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001666 }
1667 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001668 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001669 }
1670#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001671 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001672#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001673 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1674 if (_PyStatus_EXCEPTION(status)) {
1675 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001676 }
1677 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001678 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001679}
1680
1681
Victor Stinner331a6a52019-05-27 16:39:22 +02001682static PyStatus
1683config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001684{
Victor Stinner331a6a52019-05-27 16:39:22 +02001685 PyStatus status;
1686 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001687
Victor Stinner20004952019-03-26 02:31:11 +01001688 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001689 status = config_read_env_vars(config);
1690 if (_PyStatus_EXCEPTION(status)) {
1691 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001692 }
1693 }
1694
1695 /* -X options */
1696 if (config_get_xoption(config, L"showrefcount")) {
1697 config->show_ref_count = 1;
1698 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001699
Victor Stinner331a6a52019-05-27 16:39:22 +02001700 status = config_read_complex_options(config);
1701 if (_PyStatus_EXCEPTION(status)) {
1702 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001703 }
1704
Victor Stinner6c785c02018-08-01 17:56:14 +02001705 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001706 status = config_init_home(config);
1707 if (_PyStatus_EXCEPTION(status)) {
1708 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001709 }
1710 }
1711
Steve Dower177a41a2018-11-17 20:41:48 -08001712 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001713 status = config_init_executable(config);
1714 if (_PyStatus_EXCEPTION(status)) {
1715 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001716 }
1717 }
1718
Sandro Mani8f023a22020-06-08 17:28:11 +02001719 if(config->platlibdir == NULL) {
1720 status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR,
1721 "PLATLIBDIR macro");
1722 if (_PyStatus_EXCEPTION(status)) {
1723 return status;
1724 }
1725 }
1726
Victor Stinner6c785c02018-08-01 17:56:14 +02001727 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001728 status = _PyConfig_InitPathConfig(config);
1729 if (_PyStatus_EXCEPTION(status)) {
1730 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001731 }
1732 }
1733
1734 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001735 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001736 if (config->faulthandler < 0) {
1737 config->faulthandler = 1;
1738 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001739 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001740 if (config->faulthandler < 0) {
1741 config->faulthandler = 0;
1742 }
1743 if (config->tracemalloc < 0) {
1744 config->tracemalloc = 0;
1745 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001746 if (config->use_hash_seed < 0) {
1747 config->use_hash_seed = 0;
1748 config->hash_seed = 0;
1749 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001750
Victor Stinner70fead22018-08-29 13:45:34 +02001751 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001752 status = config_init_fs_encoding(config, preconfig);
1753 if (_PyStatus_EXCEPTION(status)) {
1754 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001755 }
1756 }
1757
Victor Stinner331a6a52019-05-27 16:39:22 +02001758 status = config_init_stdio_encoding(config, preconfig);
1759 if (_PyStatus_EXCEPTION(status)) {
1760 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001761 }
1762
Victor Stinner62599762019-03-15 16:03:23 +01001763 if (config->argv.length < 1) {
1764 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001765 status = PyWideStringList_Append(&config->argv, L"");
1766 if (_PyStatus_EXCEPTION(status)) {
1767 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001768 }
1769 }
Victor Stinner870b0352019-05-17 03:15:12 +02001770
1771 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001772 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1773 L"default");
1774 if (_PyStatus_EXCEPTION(status)) {
1775 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001776 }
1777 }
1778
1779 if (config->configure_c_stdio < 0) {
1780 config->configure_c_stdio = 1;
1781 }
1782
Victor Stinner331a6a52019-05-27 16:39:22 +02001783 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001784}
Victor Stinner5ed69952018-11-06 15:59:52 +01001785
1786
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001787static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001788config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001789{
1790#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1791 /* don't translate newlines (\r\n <=> \n) */
1792 _setmode(fileno(stdin), O_BINARY);
1793 _setmode(fileno(stdout), O_BINARY);
1794 _setmode(fileno(stderr), O_BINARY);
1795#endif
1796
1797 if (!config->buffered_stdio) {
1798#ifdef HAVE_SETVBUF
1799 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1800 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1801 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1802#else /* !HAVE_SETVBUF */
1803 setbuf(stdin, (char *)NULL);
1804 setbuf(stdout, (char *)NULL);
1805 setbuf(stderr, (char *)NULL);
1806#endif /* !HAVE_SETVBUF */
1807 }
1808 else if (config->interactive) {
1809#ifdef MS_WINDOWS
1810 /* Doesn't have to have line-buffered -- use unbuffered */
1811 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1812 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1813#else /* !MS_WINDOWS */
1814#ifdef HAVE_SETVBUF
1815 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1816 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1817#endif /* HAVE_SETVBUF */
1818#endif /* !MS_WINDOWS */
1819 /* Leave stderr alone - it should be unbuffered anyway. */
1820 }
1821}
1822
1823
1824/* Write the configuration:
1825
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001826 - set Py_xxx global configuration variables
1827 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinnere81f6e62020-06-08 18:12:59 +02001828PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +02001829_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001830{
Victor Stinner331a6a52019-05-27 16:39:22 +02001831 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001832
1833 if (config->configure_c_stdio) {
1834 config_init_stdio(config);
1835 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001836
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001837 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001838 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001839 preconfig->isolated = config->isolated;
1840 preconfig->use_environment = config->use_environment;
1841 preconfig->dev_mode = config->dev_mode;
Victor Stinnere81f6e62020-06-08 18:12:59 +02001842
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02001843 if (_Py_SetArgcArgv(config->orig_argv.length,
1844 config->orig_argv.items) < 0)
Victor Stinnere81f6e62020-06-08 18:12:59 +02001845 {
1846 return _PyStatus_NO_MEMORY();
1847 }
1848 return _PyStatus_OK();
Victor Stinner5ed69952018-11-06 15:59:52 +01001849}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001850
1851
Victor Stinner331a6a52019-05-27 16:39:22 +02001852/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001853
1854static void
Victor Stinner2f549082019-03-29 15:13:46 +01001855config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001856{
Victor Stinner2f549082019-03-29 15:13:46 +01001857 FILE *f = error ? stderr : stdout;
1858
1859 fprintf(f, usage_line, program);
1860 if (error)
1861 fprintf(f, "Try `python -h' for more information.\n");
1862 else {
1863 fputs(usage_1, f);
1864 fputs(usage_2, f);
1865 fputs(usage_3, f);
1866 fprintf(f, usage_4, (wint_t)DELIM);
1867 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1868 fputs(usage_6, f);
1869 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001870}
1871
1872
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001873/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001874static PyStatus
1875config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001876 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001877{
Victor Stinner331a6a52019-05-27 16:39:22 +02001878 PyStatus status;
1879 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001880 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001881 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001882
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001883 _PyOS_ResetGetOpt();
1884 do {
1885 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001886 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001887 if (c == EOF) {
1888 break;
1889 }
1890
1891 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001892 if (config->run_command == NULL) {
1893 /* -c is the last option; following arguments
1894 that look like options are left for the
1895 command to interpret. */
1896 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1897 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1898 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001899 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001900 }
1901 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1902 command[len - 2] = '\n';
1903 command[len - 1] = 0;
1904 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001905 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001906 break;
1907 }
1908
1909 if (c == 'm') {
1910 /* -m is the last option; following arguments
1911 that look like options are left for the
1912 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001913 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001914 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1915 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001916 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001917 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001918 }
1919 break;
1920 }
1921
1922 switch (c) {
1923 case 0:
1924 // Handle long option.
1925 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001926 if (wcscmp(_PyOS_optarg, L"always") == 0
1927 || wcscmp(_PyOS_optarg, L"never") == 0
1928 || wcscmp(_PyOS_optarg, L"default") == 0)
1929 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001930 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1931 _PyOS_optarg);
1932 if (_PyStatus_EXCEPTION(status)) {
1933 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001934 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001935 } else {
1936 fprintf(stderr, "--check-hash-based-pycs must be one of "
1937 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001938 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001939 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001940 }
1941 break;
1942
1943 case 'b':
1944 config->bytes_warning++;
1945 break;
1946
1947 case 'd':
1948 config->parser_debug++;
1949 break;
1950
1951 case 'i':
1952 config->inspect++;
1953 config->interactive++;
1954 break;
1955
Victor Stinner6dcb5422019-03-05 02:44:12 +01001956 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001957 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001958 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001959 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001960 break;
1961
1962 /* case 'J': reserved for Jython */
1963
1964 case 'O':
1965 config->optimization_level++;
1966 break;
1967
1968 case 'B':
1969 config->write_bytecode = 0;
1970 break;
1971
1972 case 's':
1973 config->user_site_directory = 0;
1974 break;
1975
1976 case 'S':
1977 config->site_import = 0;
1978 break;
1979
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001980 case 't':
1981 /* ignored for backwards compatibility */
1982 break;
1983
1984 case 'u':
1985 config->buffered_stdio = 0;
1986 break;
1987
1988 case 'v':
1989 config->verbose++;
1990 break;
1991
1992 case 'x':
1993 config->skip_source_first_line = 1;
1994 break;
1995
1996 case 'h':
1997 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001998 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001999 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002000
2001 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01002002 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002003 break;
2004
2005 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002006 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2007 if (_PyStatus_EXCEPTION(status)) {
2008 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002009 }
2010 break;
2011
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002012 case 'q':
2013 config->quiet++;
2014 break;
2015
2016 case 'R':
2017 config->use_hash_seed = 0;
2018 break;
2019
2020 /* This space reserved for other options */
2021
2022 default:
2023 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002024 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002025 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002026 }
2027 } while (1);
2028
Victor Stinner2f549082019-03-29 15:13:46 +01002029 if (print_version) {
2030 printf("Python %s\n",
2031 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002032 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002033 }
2034
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002035 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002036 && _PyOS_optind < argv->length
2037 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002038 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002039 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002040 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002041 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002042 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002043 }
2044 }
2045
2046 if (config->run_command != NULL || config->run_module != NULL) {
2047 /* Backup _PyOS_optind */
2048 _PyOS_optind--;
2049 }
2050
Victor Stinnerae239f62019-05-16 17:02:56 +02002051 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002052
Victor Stinner331a6a52019-05-27 16:39:22 +02002053 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002054}
2055
2056
2057#ifdef MS_WINDOWS
2058# define WCSTOK wcstok_s
2059#else
2060# define WCSTOK wcstok
2061#endif
2062
2063/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002064static PyStatus
2065config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002066{
Victor Stinner331a6a52019-05-27 16:39:22 +02002067 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002068 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2069 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002070 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002071 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002072 if (_PyStatus_EXCEPTION(status)) {
2073 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002074 }
2075
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002076 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002077 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002078 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002079 }
2080
2081
2082 wchar_t *warning, *context = NULL;
2083 for (warning = WCSTOK(env, L",", &context);
2084 warning != NULL;
2085 warning = WCSTOK(NULL, L",", &context))
2086 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002087 status = PyWideStringList_Append(warnoptions, warning);
2088 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002089 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002090 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002091 }
2092 }
2093 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002094 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002095}
2096
2097
Victor Stinner331a6a52019-05-27 16:39:22 +02002098static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002099warnoptions_append(PyConfig *config, PyWideStringList *options,
2100 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002101{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002102 /* config_init_warnoptions() add existing config warnoptions at the end:
2103 ensure that the new option is not already present in this list to
2104 prevent change the options order whne config_init_warnoptions() is
2105 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002106 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002107 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002108 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002109 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002110 if (_PyWideStringList_Find(options, option)) {
2111 /* Already present: do nothing */
2112 return _PyStatus_OK();
2113 }
2114 return PyWideStringList_Append(options, option);
2115}
2116
2117
2118static PyStatus
2119warnoptions_extend(PyConfig *config, PyWideStringList *options,
2120 const PyWideStringList *options2)
2121{
2122 const Py_ssize_t len = options2->length;
2123 wchar_t *const *items = options2->items;
2124
2125 for (Py_ssize_t i = 0; i < len; i++) {
2126 PyStatus status = warnoptions_append(config, options, items[i]);
2127 if (_PyStatus_EXCEPTION(status)) {
2128 return status;
2129 }
2130 }
2131 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002132}
2133
2134
Victor Stinner331a6a52019-05-27 16:39:22 +02002135static PyStatus
2136config_init_warnoptions(PyConfig *config,
2137 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002138 const PyWideStringList *env_warnoptions,
2139 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002140{
Victor Stinner331a6a52019-05-27 16:39:22 +02002141 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002142 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002143
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002144 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002145 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002146 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002147 * - PyConfig.dev_mode: "default" filter
2148 * - PYTHONWARNINGS environment variable
2149 * - '-W' command line options
2150 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2151 * "default::BytesWarning" or "error::BytesWarning" filter
2152 * - early PySys_AddWarnOption() calls
2153 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002154 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002155 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2156 * module works on the basis of "the most recently added filter will be
2157 * checked first", we add the lowest precedence entries first so that later
2158 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002159 */
2160
Victor Stinner20004952019-03-26 02:31:11 +01002161 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002162 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002163 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002164 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002165 }
2166 }
2167
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002168 status = warnoptions_extend(config, &options, env_warnoptions);
2169 if (_PyStatus_EXCEPTION(status)) {
2170 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002171 }
2172
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002173 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2174 if (_PyStatus_EXCEPTION(status)) {
2175 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002176 }
2177
2178 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2179 * don't even try to emit a warning, so we skip setting the filter in that
2180 * case.
2181 */
2182 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002183 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002184 if (config->bytes_warning> 1) {
2185 filter = L"error::BytesWarning";
2186 }
2187 else {
2188 filter = L"default::BytesWarning";
2189 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002190 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002191 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002192 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002193 }
2194 }
Victor Stinner120b7072019-08-23 18:03:08 +01002195
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002196 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002197 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002198 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002199 }
2200
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002201 /* Always add all PyConfig.warnoptions options */
2202 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2203 if (_PyStatus_EXCEPTION(status)) {
2204 goto error;
2205 }
2206
2207 _PyWideStringList_Clear(&config->warnoptions);
2208 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002209 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002210
2211error:
2212 _PyWideStringList_Clear(&options);
2213 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002214}
2215
2216
Victor Stinner331a6a52019-05-27 16:39:22 +02002217static PyStatus
2218config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002219{
Victor Stinner331a6a52019-05-27 16:39:22 +02002220 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002221 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002222
Victor Stinner74f65682019-03-15 15:08:05 +01002223 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002224 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002225 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002226 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2227 if (_PyStatus_EXCEPTION(status)) {
2228 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002229 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002230 }
2231 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002232 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002233 slice.length = cmdline_argv->length - opt_index;
2234 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002235 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2236 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002237 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002238 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002239 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002240
2241 wchar_t *arg0 = NULL;
2242 if (config->run_command != NULL) {
2243 /* Force sys.argv[0] = '-c' */
2244 arg0 = L"-c";
2245 }
2246 else if (config->run_module != NULL) {
2247 /* Force sys.argv[0] = '-m'*/
2248 arg0 = L"-m";
2249 }
Victor Stinner3939c322019-06-25 15:02:43 +02002250
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002251 if (arg0 != NULL) {
2252 arg0 = _PyMem_RawWcsdup(arg0);
2253 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002254 _PyWideStringList_Clear(&config_argv);
2255 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002256 }
2257
Victor Stinnerfa153762019-03-20 04:25:38 +01002258 PyMem_RawFree(config_argv.items[0]);
2259 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002260 }
2261
Victor Stinner331a6a52019-05-27 16:39:22 +02002262 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002263 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002264 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002265}
2266
2267
Victor Stinner331a6a52019-05-27 16:39:22 +02002268static PyStatus
2269core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002270{
Victor Stinner331a6a52019-05-27 16:39:22 +02002271 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002272
Victor Stinnercab5d072019-05-17 19:01:14 +02002273 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002274 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2275 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002276 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002277 }
2278
Victor Stinner331a6a52019-05-27 16:39:22 +02002279 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002280
2281 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2282 if (_PyStatus_EXCEPTION(status)) {
2283 return status;
2284 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002285
Victor Stinner331a6a52019-05-27 16:39:22 +02002286 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002287
Victor Stinner331a6a52019-05-27 16:39:22 +02002288 status = _PyPreCmdline_Read(precmdline, &preconfig);
2289 if (_PyStatus_EXCEPTION(status)) {
2290 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002291 }
2292
Victor Stinner331a6a52019-05-27 16:39:22 +02002293 status = _PyPreCmdline_SetConfig(precmdline, config);
2294 if (_PyStatus_EXCEPTION(status)) {
2295 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002296 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002297 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002298}
2299
2300
Victor Stinner3939c322019-06-25 15:02:43 +02002301/* Get run_filename absolute path */
2302static PyStatus
2303config_run_filename_abspath(PyConfig *config)
2304{
2305 if (!config->run_filename) {
2306 return _PyStatus_OK();
2307 }
2308
2309#ifndef MS_WINDOWS
2310 if (_Py_isabs(config->run_filename)) {
2311 /* path is already absolute */
2312 return _PyStatus_OK();
2313 }
2314#endif
2315
2316 wchar_t *abs_filename;
2317 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2318 /* failed to get the absolute path of the command line filename:
2319 ignore the error, keep the relative path */
2320 return _PyStatus_OK();
2321 }
2322 if (abs_filename == NULL) {
2323 return _PyStatus_NO_MEMORY();
2324 }
2325
2326 PyMem_RawFree(config->run_filename);
2327 config->run_filename = abs_filename;
2328 return _PyStatus_OK();
2329}
2330
2331
Victor Stinner331a6a52019-05-27 16:39:22 +02002332static PyStatus
2333config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002334{
Victor Stinner331a6a52019-05-27 16:39:22 +02002335 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002336 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2337 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2338 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002339
Victor Stinnerae239f62019-05-16 17:02:56 +02002340 if (config->parse_argv < 0) {
2341 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002342 }
Victor Stinner870b0352019-05-17 03:15:12 +02002343
Victor Stinnerfed02e12019-05-17 11:12:09 +02002344 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002345 status = config_init_program_name(config);
2346 if (_PyStatus_EXCEPTION(status)) {
2347 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002348 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002349 }
Victor Stinner2f549082019-03-29 15:13:46 +01002350
Victor Stinnerae239f62019-05-16 17:02:56 +02002351 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002352 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002353 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2354 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002355 goto done;
2356 }
2357
Victor Stinner3939c322019-06-25 15:02:43 +02002358 status = config_run_filename_abspath(config);
2359 if (_PyStatus_EXCEPTION(status)) {
2360 goto done;
2361 }
2362
Victor Stinner331a6a52019-05-27 16:39:22 +02002363 status = config_update_argv(config, opt_index);
2364 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002365 goto done;
2366 }
Victor Stinner2f549082019-03-29 15:13:46 +01002367 }
Victor Stinner3939c322019-06-25 15:02:43 +02002368 else {
2369 status = config_run_filename_abspath(config);
2370 if (_PyStatus_EXCEPTION(status)) {
2371 goto done;
2372 }
2373 }
Victor Stinner2f549082019-03-29 15:13:46 +01002374
Victor Stinner2f549082019-03-29 15:13:46 +01002375 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002376 status = config_init_env_warnoptions(config, &env_warnoptions);
2377 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002378 goto done;
2379 }
2380 }
2381
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002382 /* Handle early PySys_AddWarnOption() calls */
2383 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2384 if (_PyStatus_EXCEPTION(status)) {
2385 goto done;
2386 }
2387
Victor Stinner331a6a52019-05-27 16:39:22 +02002388 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002389 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002390 &env_warnoptions,
2391 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002392 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002393 goto done;
2394 }
2395
Victor Stinner331a6a52019-05-27 16:39:22 +02002396 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002397
2398done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002399 _PyWideStringList_Clear(&cmdline_warnoptions);
2400 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002401 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002402 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002403}
2404
2405
Victor Stinner331a6a52019-05-27 16:39:22 +02002406PyStatus
2407_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002408{
Victor Stinner331a6a52019-05-27 16:39:22 +02002409 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2410 if (_PyStatus_EXCEPTION(status)) {
2411 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002412 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002413
Victor Stinner5f38b842019-05-01 02:30:12 +02002414 return _PyArgv_AsWstrList(args, &config->argv);
2415}
2416
2417
Victor Stinner70005ac2019-05-02 15:25:34 -04002418/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2419 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002420PyStatus
2421PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002422{
2423 _PyArgv args = {
2424 .argc = argc,
2425 .use_bytes_argv = 1,
2426 .bytes_argv = argv,
2427 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002428 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002429}
2430
2431
Victor Stinner331a6a52019-05-27 16:39:22 +02002432PyStatus
2433PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002434{
2435 _PyArgv args = {
2436 .argc = argc,
2437 .use_bytes_argv = 0,
2438 .bytes_argv = NULL,
2439 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002440 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002441}
2442
2443
Victor Stinner36242fd2019-07-01 19:13:50 +02002444PyStatus
2445PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2446 Py_ssize_t length, wchar_t **items)
2447{
2448 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2449 if (_PyStatus_EXCEPTION(status)) {
2450 return status;
2451 }
2452
2453 PyWideStringList list2 = {.length = length, .items = items};
2454 if (_PyWideStringList_Copy(list, &list2) < 0) {
2455 return _PyStatus_NO_MEMORY();
2456 }
2457 return _PyStatus_OK();
2458}
2459
2460
Victor Stinner331a6a52019-05-27 16:39:22 +02002461/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002462
2463 * Command line arguments
2464 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002465 * Py_xxx global configuration variables
2466
2467 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002468PyStatus
2469PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002470{
Victor Stinner331a6a52019-05-27 16:39:22 +02002471 PyStatus status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002472
Victor Stinner331a6a52019-05-27 16:39:22 +02002473 status = _Py_PreInitializeFromConfig(config, NULL);
2474 if (_PyStatus_EXCEPTION(status)) {
2475 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002476 }
2477
Victor Stinner331a6a52019-05-27 16:39:22 +02002478 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002479
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002480 if (config->orig_argv.length == 0
Victor Stinnere81f6e62020-06-08 18:12:59 +02002481 && !(config->argv.length == 1
2482 && wcscmp(config->argv.items[0], L"") == 0))
2483 {
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002484 if (_PyWideStringList_Copy(&config->orig_argv, &config->argv) < 0) {
Victor Stinnere81f6e62020-06-08 18:12:59 +02002485 return _PyStatus_NO_MEMORY();
2486 }
Victor Stinnercab5d072019-05-17 19:01:14 +02002487 }
2488
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002489 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002490 status = core_read_precmdline(config, &precmdline);
2491 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002492 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002493 }
2494
Victor Stinner870b0352019-05-17 03:15:12 +02002495 assert(config->isolated >= 0);
2496 if (config->isolated) {
2497 config->use_environment = 0;
2498 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002499 }
2500
Victor Stinner331a6a52019-05-27 16:39:22 +02002501 status = config_read_cmdline(config);
2502 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002503 goto done;
2504 }
2505
Victor Stinner120b7072019-08-23 18:03:08 +01002506 /* Handle early PySys_AddXOption() calls */
2507 status = _PySys_ReadPreinitXOptions(config);
2508 if (_PyStatus_EXCEPTION(status)) {
2509 goto done;
2510 }
2511
Victor Stinner331a6a52019-05-27 16:39:22 +02002512 status = config_read(config);
2513 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002514 goto done;
2515 }
2516
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002517 /* Check config consistency */
2518 assert(config->isolated >= 0);
2519 assert(config->use_environment >= 0);
2520 assert(config->dev_mode >= 0);
2521 assert(config->install_signal_handlers >= 0);
2522 assert(config->use_hash_seed >= 0);
2523 assert(config->faulthandler >= 0);
2524 assert(config->tracemalloc >= 0);
2525 assert(config->site_import >= 0);
2526 assert(config->bytes_warning >= 0);
2527 assert(config->inspect >= 0);
2528 assert(config->interactive >= 0);
2529 assert(config->optimization_level >= 0);
2530 assert(config->parser_debug >= 0);
2531 assert(config->write_bytecode >= 0);
2532 assert(config->verbose >= 0);
2533 assert(config->quiet >= 0);
2534 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002535 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002536 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002537 assert(config->buffered_stdio >= 0);
2538 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002539 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002540 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2541 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002542 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2543 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2544 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002545 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002546 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002547 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002548 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002549 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002550 assert(config->prefix != NULL);
2551 assert(config->base_prefix != NULL);
2552 assert(config->exec_prefix != NULL);
2553 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002554 }
Sandro Mani8f023a22020-06-08 17:28:11 +02002555 assert(config->platlibdir != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002556 assert(config->filesystem_encoding != NULL);
2557 assert(config->filesystem_errors != NULL);
2558 assert(config->stdio_encoding != NULL);
2559 assert(config->stdio_errors != NULL);
2560#ifdef MS_WINDOWS
2561 assert(config->legacy_windows_stdio >= 0);
2562#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002563 /* -c and -m options are exclusive */
2564 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002565 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002566 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002567 assert(config->pathconfig_warnings >= 0);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002568 assert(_PyWideStringList_CheckConsistency(&config->orig_argv));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002569
Victor Stinner331a6a52019-05-27 16:39:22 +02002570 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002571
2572done:
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002573 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002574 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002575}
Victor Stinner1075d162019-03-25 23:19:57 +01002576
2577
2578PyObject*
2579_Py_GetConfigsAsDict(void)
2580{
Victor Stinner331a6a52019-05-27 16:39:22 +02002581 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002582 PyObject *dict = NULL;
2583
Victor Stinner331a6a52019-05-27 16:39:22 +02002584 result = PyDict_New();
2585 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002586 goto error;
2587 }
2588
Victor Stinner331a6a52019-05-27 16:39:22 +02002589 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002590 dict = _Py_GetGlobalVariablesAsDict();
2591 if (dict == NULL) {
2592 goto error;
2593 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002594 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002595 goto error;
2596 }
2597 Py_CLEAR(dict);
2598
2599 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002600 PyThreadState *tstate = _PyThreadState_GET();
2601 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002602 dict = _PyPreConfig_AsDict(pre_config);
2603 if (dict == NULL) {
2604 goto error;
2605 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002606 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002607 goto error;
2608 }
2609 Py_CLEAR(dict);
2610
2611 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002612 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinner331a6a52019-05-27 16:39:22 +02002613 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002614 if (dict == NULL) {
2615 goto error;
2616 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002617 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002618 goto error;
2619 }
2620 Py_CLEAR(dict);
2621
Victor Stinner8f427482020-07-08 00:20:37 +02002622 /* path config */
2623 dict = _PyPathConfig_AsDict();
2624 if (dict == NULL) {
2625 goto error;
2626 }
2627 if (PyDict_SetItemString(result, "path_config", dict) < 0) {
2628 goto error;
2629 }
2630 Py_CLEAR(dict);
2631
Victor Stinner331a6a52019-05-27 16:39:22 +02002632 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002633
2634error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002635 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002636 Py_XDECREF(dict);
2637 return NULL;
2638}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002639
2640
2641static void
2642init_dump_ascii_wstr(const wchar_t *str)
2643{
2644 if (str == NULL) {
2645 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002646 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002647 }
2648
2649 PySys_WriteStderr("'");
2650 for (; *str != L'\0'; str++) {
Victor Stinner640e8e12020-09-09 12:07:17 +02002651 unsigned int ch = (unsigned int)*str;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002652 if (ch == L'\'') {
2653 PySys_WriteStderr("\\'");
2654 } else if (0x20 <= ch && ch < 0x7f) {
Samuel Marksc3229482020-09-21 18:35:17 +10002655 PySys_WriteStderr("%c", ch);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002656 }
2657 else if (ch <= 0xff) {
2658 PySys_WriteStderr("\\x%02x", ch);
2659 }
2660#if SIZEOF_WCHAR_T > 2
2661 else if (ch > 0xffff) {
2662 PySys_WriteStderr("\\U%08x", ch);
2663 }
2664#endif
2665 else {
2666 PySys_WriteStderr("\\u%04x", ch);
2667 }
2668 }
2669 PySys_WriteStderr("'");
2670}
2671
2672
2673/* Dump the Python path configuration into sys.stderr */
2674void
2675_Py_DumpPathConfig(PyThreadState *tstate)
2676{
2677 PyObject *exc_type, *exc_value, *exc_tb;
2678 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2679
2680 PySys_WriteStderr("Python path configuration:\n");
2681
2682#define DUMP_CONFIG(NAME, FIELD) \
2683 do { \
2684 PySys_WriteStderr(" " NAME " = "); \
2685 init_dump_ascii_wstr(config->FIELD); \
2686 PySys_WriteStderr("\n"); \
2687 } while (0)
2688
Victor Stinnerda7933e2020-04-13 03:04:28 +02002689 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002690 DUMP_CONFIG("PYTHONHOME", home);
2691 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2692 DUMP_CONFIG("program name", program_name);
2693 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2694 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2695 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2696 PySys_WriteStderr(" import site = %i\n", config->site_import);
2697#undef DUMP_CONFIG
2698
2699#define DUMP_SYS(NAME) \
2700 do { \
2701 obj = PySys_GetObject(#NAME); \
2702 PySys_FormatStderr(" sys.%s = ", #NAME); \
2703 if (obj != NULL) { \
2704 PySys_FormatStderr("%A", obj); \
2705 } \
2706 else { \
2707 PySys_WriteStderr("(not set)"); \
2708 } \
2709 PySys_FormatStderr("\n"); \
2710 } while (0)
2711
2712 PyObject *obj;
2713 DUMP_SYS(_base_executable);
2714 DUMP_SYS(base_prefix);
2715 DUMP_SYS(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +02002716 DUMP_SYS(platlibdir);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002717 DUMP_SYS(executable);
2718 DUMP_SYS(prefix);
2719 DUMP_SYS(exec_prefix);
2720#undef DUMP_SYS
2721
2722 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2723 if (sys_path != NULL && PyList_Check(sys_path)) {
2724 PySys_WriteStderr(" sys.path = [\n");
2725 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2726 for (Py_ssize_t i=0; i < len; i++) {
2727 PyObject *path = PyList_GET_ITEM(sys_path, i);
2728 PySys_FormatStderr(" %A,\n", path);
2729 }
2730 PySys_WriteStderr(" ]\n");
2731 }
2732
2733 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2734}