blob: a930b5d38fa26ba9ae16b98bddbd11efff35d08f [file] [log] [blame]
Victor Stinner6c785c02018-08-01 17:56:14 +02001#include "Python.h"
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002#include "osdefs.h" /* DELIM */
Victor Stinner9fc57a32018-11-07 00:44:03 +01003#include "pycore_fileutils.h"
Victor Stinner95e2cbf2019-03-01 16:25:19 +01004#include "pycore_getopt.h"
Victor Stinnerc5c64252019-09-23 15:59:00 +02005#include "pycore_initconfig.h"
6#include "pycore_pathconfig.h"
7#include "pycore_pyerrors.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01008#include "pycore_pylifecycle.h"
9#include "pycore_pymem.h"
Victor Stinner6d5ee972019-03-23 12:05:43 +010010#include "pycore_pystate.h" /* _PyRuntime */
Victor Stinner95e2cbf2019-03-01 16:25:19 +010011#include <locale.h> /* setlocale() */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020012#ifdef HAVE_LANGINFO_H
Victor Stinner95e2cbf2019-03-01 16:25:19 +010013# include <langinfo.h> /* nl_langinfo(CODESET) */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020014#endif
Victor Stinner95e2cbf2019-03-01 16:25:19 +010015#if defined(MS_WINDOWS) || defined(__CYGWIN__)
16# include <windows.h> /* GetACP() */
17# ifdef HAVE_IO_H
18# include <io.h>
19# endif
20# ifdef HAVE_FCNTL_H
21# include <fcntl.h> /* O_BINARY */
22# endif
Victor Stinnerb2457ef2018-08-29 13:25:36 +020023#endif
24
Victor Stinner6c785c02018-08-01 17:56:14 +020025
Victor Stinner95e2cbf2019-03-01 16:25:19 +010026/* --- Command line options --------------------------------------- */
27
Victor Stinner95e2cbf2019-03-01 16:25:19 +010028/* Short usage message (with %s for argv0) */
29static const char usage_line[] =
30"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
31
32/* Long usage message, split into parts < 512 bytes */
33static const char usage_1[] = "\
34Options and arguments (and corresponding environment variables):\n\
35-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
36 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
37-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
38-c cmd : program passed in as string (terminates option list)\n\
39-d : debug output from parser; also PYTHONDEBUG=x\n\
40-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
41-h : print this help message and exit (also --help)\n\
42";
43static const char usage_2[] = "\
44-i : inspect interactively after running script; forces a prompt even\n\
45 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
46-I : isolate Python from the user's environment (implies -E and -s)\n\
47-m mod : run library module as a script (terminates option list)\n\
48-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
49 .pyc extension; also PYTHONOPTIMIZE=x\n\
50-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
51 .pyc extension\n\
52-q : don't print version and copyright messages on interactive startup\n\
53-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
54-S : don't imply 'import site' on initialization\n\
55";
56static const char usage_3[] = "\
57-u : force the stdout and stderr streams to be unbuffered;\n\
58 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
59-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
60 can be supplied multiple times to increase verbosity\n\
61-V : print the Python version number and exit (also --version)\n\
62 when given twice, print more information about the build\n\
63-W arg : warning control; arg is action:message:category:module:lineno\n\
64 also PYTHONWARNINGS=arg\n\
65-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
Pablo Galindo13951c72020-02-23 20:48:27 +000066-X opt : set implementation-specific option. The following options are available:\n\
67\n\
68 -X faulthandler: enable faulthandler\n\
69 -X showrefcount: output the total reference count and number of used\n\
70 memory blocks when the program finishes or after each statement in the\n\
71 interactive interpreter. This only works on debug builds\n\
72 -X tracemalloc: start tracing Python memory allocations using the\n\
73 tracemalloc module. By default, only the most recent frame is stored in a\n\
74 traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\
75 traceback limit of NFRAME frames\n\
76 -X showalloccount: output the total count of allocated objects for each\n\
77 type when the program finishes. This only works when Python was built with\n\
78 COUNT_ALLOCS defined\n\
79 -X importtime: show how long each import takes. It shows module name,\n\
80 cumulative time (including nested imports) and self time (excluding\n\
81 nested imports). Note that its output may be broken in multi-threaded\n\
82 application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
83 -X dev: enable CPythons development mode”, introducing additional runtime\n\
84 checks which are too expensive to be enabled by default. Effect of the\n\
85 developer mode:\n\
86 * Add default warning filter, as -W default\n\
87 * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\
88 * Enable the faulthandler module to dump the Python traceback on a crash\n\
89 * Enable asyncio debug mode\n\
90 * Set the dev_mode attribute of sys.flags to True\n\
91 * io.IOBase destructor logs close() exceptions\n\
92 -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\
93 locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\
94 otherwise activate automatically)\n\
95 -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
96 given directory instead of to the code tree\n\
97\n\
Victor Stinner95e2cbf2019-03-01 16:25:19 +010098--check-hash-based-pycs always|default|never:\n\
99 control how Python invalidates hash-based .pyc files\n\
100";
101static const char usage_4[] = "\
102file : program read from script file\n\
103- : program read from stdin (default; interactive mode if a tty)\n\
104arg ...: arguments passed to program in sys.argv[1:]\n\n\
105Other environment variables:\n\
106PYTHONSTARTUP: file executed on interactive startup (no default)\n\
107PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
108 default module search path. The result is sys.path.\n\
109";
110static const char usage_5[] =
111"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
112" The default module search path uses %s.\n"
113"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
Miss Islington (bot)4a5db782019-12-14 02:38:35 -0800114"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"
Miss Islington (bot)076d0b92019-08-24 03:19:51 -0700119" 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
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -0700308 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
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700333PyWideStringList_Insert(PyWideStringList *list,
334 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100335{
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700336 Py_ssize_t len = list->length;
337 if (len == PY_SSIZE_T_MAX) {
Kyle Stanley24b5b362019-07-21 22:48:45 -0400338 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200339 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100340 }
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700341 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
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700353 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
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700360 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
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700374PyWideStringList_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
546/* Make the *original* argc/argv available to other modules.
547 This is rare, but it is needed by the secureware extension. */
548void
549Py_GetArgcArgv(int *argc, wchar_t ***argv)
550{
Victor Stinner74f65682019-03-15 15:08:05 +0100551 *argc = (int)orig_argv.length;
552 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100553}
554
555
Victor Stinner331a6a52019-05-27 16:39:22 +0200556/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100557
558#define DECODE_LOCALE_ERR(NAME, LEN) \
559 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200560 ? _PyStatus_ERR("cannot decode " NAME) \
561 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100562
Victor Stinner6e128382019-09-28 04:50:43 +0200563
Victor Stinner6c785c02018-08-01 17:56:14 +0200564/* Free memory allocated in config, but don't clear all attributes */
565void
Victor Stinner331a6a52019-05-27 16:39:22 +0200566PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200567{
568#define CLEAR(ATTR) \
569 do { \
570 PyMem_RawFree(ATTR); \
571 ATTR = NULL; \
572 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200573
574 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200575 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200576 CLEAR(config->home);
577 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200578
Victor Stinner331a6a52019-05-27 16:39:22 +0200579 _PyWideStringList_Clear(&config->argv);
580 _PyWideStringList_Clear(&config->warnoptions);
581 _PyWideStringList_Clear(&config->xoptions);
582 _PyWideStringList_Clear(&config->module_search_paths);
583 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200584
585 CLEAR(config->executable);
Steve Dower323e7432019-06-29 14:28:59 -0700586 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200587 CLEAR(config->prefix);
588 CLEAR(config->base_prefix);
589 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200590 CLEAR(config->base_exec_prefix);
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 Stinner6c785c02018-08-01 17:56:14 +0200600#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200601}
602
603
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700604void
Victor Stinner331a6a52019-05-27 16:39:22 +0200605_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200606{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200607 memset(config, 0, sizeof(*config));
Victor Stinner6e128382019-09-28 04:50:43 +0200608
Victor Stinner022be022019-05-22 23:58:50 +0200609 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200610 config->isolated = -1;
611 config->use_environment = -1;
612 config->dev_mode = -1;
613 config->install_signal_handlers = 1;
614 config->use_hash_seed = -1;
615 config->faulthandler = -1;
616 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200617 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200618 config->parse_argv = 0;
619 config->site_import = -1;
620 config->bytes_warning = -1;
621 config->inspect = -1;
622 config->interactive = -1;
623 config->optimization_level = -1;
624 config->parser_debug= -1;
625 config->write_bytecode = -1;
626 config->verbose = -1;
627 config->quiet = -1;
628 config->user_site_directory = -1;
629 config->configure_c_stdio = 0;
630 config->buffered_stdio = -1;
631 config->_install_importlib = 1;
632 config->check_hash_pycs_mode = NULL;
633 config->pathconfig_warnings = -1;
634 config->_init_main = 1;
635#ifdef MS_WINDOWS
636 config->legacy_windows_stdio = -1;
637#endif
638}
639
640
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700641static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200642config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200643{
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700644 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200645
646 config->isolated = 0;
647 config->use_environment = 1;
648 config->site_import = 1;
649 config->bytes_warning = 0;
650 config->inspect = 0;
651 config->interactive = 0;
652 config->optimization_level = 0;
653 config->parser_debug= 0;
654 config->write_bytecode = 1;
655 config->verbose = 0;
656 config->quiet = 0;
657 config->user_site_directory = 1;
658 config->buffered_stdio = 1;
659 config->pathconfig_warnings = 1;
660#ifdef MS_WINDOWS
661 config->legacy_windows_stdio = 0;
662#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200663}
664
665
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700666void
Victor Stinner331a6a52019-05-27 16:39:22 +0200667PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200668{
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700669 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200670
Victor Stinner022be022019-05-22 23:58:50 +0200671 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200672 config->configure_c_stdio = 1;
673 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200674}
675
676
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700677void
Victor Stinner331a6a52019-05-27 16:39:22 +0200678PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200679{
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700680 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200681
Victor Stinner022be022019-05-22 23:58:50 +0200682 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200683 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200684 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200685 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200686 config->dev_mode = 0;
687 config->install_signal_handlers = 0;
688 config->use_hash_seed = 0;
689 config->faulthandler = 0;
690 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200691 config->pathconfig_warnings = 0;
692#ifdef MS_WINDOWS
693 config->legacy_windows_stdio = 0;
694#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200695}
696
697
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200698/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200699PyStatus
700PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200701{
Victor Stinner331a6a52019-05-27 16:39:22 +0200702 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
703 if (_PyStatus_EXCEPTION(status)) {
704 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200705 }
706
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200707 wchar_t *str2;
708 if (str != NULL) {
709 str2 = _PyMem_RawWcsdup(str);
710 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200711 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200712 }
713 }
714 else {
715 str2 = NULL;
716 }
717 PyMem_RawFree(*config_str);
718 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200719 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200720}
721
722
Victor Stinner331a6a52019-05-27 16:39:22 +0200723static PyStatus
724config_set_bytes_string(PyConfig *config, wchar_t **config_str,
725 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200726{
Victor Stinner331a6a52019-05-27 16:39:22 +0200727 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
728 if (_PyStatus_EXCEPTION(status)) {
729 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400730 }
731
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200732 wchar_t *str2;
733 if (str != NULL) {
734 size_t len;
735 str2 = Py_DecodeLocale(str, &len);
736 if (str2 == NULL) {
737 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200738 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200739 }
740 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200741 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200742 }
743 }
744 }
745 else {
746 str2 = NULL;
747 }
748 PyMem_RawFree(*config_str);
749 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200750 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200751}
752
753
Victor Stinner331a6a52019-05-27 16:39:22 +0200754#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
755 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400756
757
Victor Stinner70005ac2019-05-02 15:25:34 -0400758/* Decode str using Py_DecodeLocale() and set the result into *config_str.
759 Pre-initialize Python if needed to ensure that encodings are properly
760 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200761PyStatus
762PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200763 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400764{
Victor Stinner331a6a52019-05-27 16:39:22 +0200765 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400766}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200767
768
Victor Stinner331a6a52019-05-27 16:39:22 +0200769PyStatus
770_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200771{
Victor Stinner331a6a52019-05-27 16:39:22 +0200772 PyStatus status;
Victor Stinner6e128382019-09-28 04:50:43 +0200773
Victor Stinner331a6a52019-05-27 16:39:22 +0200774 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200775
776#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200777#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200778 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200779 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
780 if (_PyStatus_EXCEPTION(status)) { \
781 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200782 } \
783 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100784#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200785 do { \
Miss Islington (bot)96f581c2019-07-01 10:39:58 -0700786 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200787 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200788 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200789 } while (0)
790
Victor Stinner6d1c4672019-05-20 11:02:00 +0200791 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100792 COPY_ATTR(isolated);
793 COPY_ATTR(use_environment);
794 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200795 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200796 COPY_ATTR(use_hash_seed);
797 COPY_ATTR(hash_seed);
798 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200799 COPY_ATTR(faulthandler);
800 COPY_ATTR(tracemalloc);
801 COPY_ATTR(import_time);
802 COPY_ATTR(show_ref_count);
803 COPY_ATTR(show_alloc_count);
804 COPY_ATTR(dump_refs);
805 COPY_ATTR(malloc_stats);
806
Victor Stinner124b9eb2018-08-29 01:29:06 +0200807 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200808 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200809 COPY_WSTR_ATTR(home);
810 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200811
Victor Stinnerae239f62019-05-16 17:02:56 +0200812 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100813 COPY_WSTRLIST(argv);
814 COPY_WSTRLIST(warnoptions);
815 COPY_WSTRLIST(xoptions);
816 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200817 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200818
Victor Stinner124b9eb2018-08-29 01:29:06 +0200819 COPY_WSTR_ATTR(executable);
Steve Dower323e7432019-06-29 14:28:59 -0700820 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200821 COPY_WSTR_ATTR(prefix);
822 COPY_WSTR_ATTR(base_prefix);
823 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200824 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200825
Victor Stinner6c785c02018-08-01 17:56:14 +0200826 COPY_ATTR(site_import);
827 COPY_ATTR(bytes_warning);
828 COPY_ATTR(inspect);
829 COPY_ATTR(interactive);
830 COPY_ATTR(optimization_level);
831 COPY_ATTR(parser_debug);
832 COPY_ATTR(write_bytecode);
833 COPY_ATTR(verbose);
834 COPY_ATTR(quiet);
835 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200836 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200837 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400838 COPY_WSTR_ATTR(filesystem_encoding);
839 COPY_WSTR_ATTR(filesystem_errors);
840 COPY_WSTR_ATTR(stdio_encoding);
841 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200842#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200843 COPY_ATTR(legacy_windows_stdio);
844#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100845 COPY_ATTR(skip_source_first_line);
846 COPY_WSTR_ATTR(run_command);
847 COPY_WSTR_ATTR(run_module);
848 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400849 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200850 COPY_ATTR(pathconfig_warnings);
851 COPY_ATTR(_init_main);
Victor Stinner6c785c02018-08-01 17:56:14 +0200852
853#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200854#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200855#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200856 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200857}
858
859
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100860static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200861config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100862{
863 PyObject *dict;
864
865 dict = PyDict_New();
866 if (dict == NULL) {
867 return NULL;
868 }
869
870#define SET_ITEM(KEY, EXPR) \
871 do { \
872 PyObject *obj = (EXPR); \
873 if (obj == NULL) { \
874 goto fail; \
875 } \
876 int res = PyDict_SetItemString(dict, (KEY), obj); \
877 Py_DECREF(obj); \
878 if (res < 0) { \
879 goto fail; \
880 } \
881 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100882#define SET_ITEM_INT(ATTR) \
883 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
884#define SET_ITEM_UINT(ATTR) \
885 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100886#define FROM_WSTRING(STR) \
887 ((STR != NULL) ? \
888 PyUnicode_FromWideChar(STR, -1) \
889 : (Py_INCREF(Py_None), Py_None))
890#define SET_ITEM_WSTR(ATTR) \
891 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
892#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200893 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100894
Victor Stinner6d1c4672019-05-20 11:02:00 +0200895 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100896 SET_ITEM_INT(isolated);
897 SET_ITEM_INT(use_environment);
898 SET_ITEM_INT(dev_mode);
899 SET_ITEM_INT(install_signal_handlers);
900 SET_ITEM_INT(use_hash_seed);
901 SET_ITEM_UINT(hash_seed);
902 SET_ITEM_INT(faulthandler);
903 SET_ITEM_INT(tracemalloc);
904 SET_ITEM_INT(import_time);
905 SET_ITEM_INT(show_ref_count);
906 SET_ITEM_INT(show_alloc_count);
907 SET_ITEM_INT(dump_refs);
908 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400909 SET_ITEM_WSTR(filesystem_encoding);
910 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100911 SET_ITEM_WSTR(pycache_prefix);
912 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200913 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100914 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100915 SET_ITEM_WSTRLIST(xoptions);
916 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200917 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100918 SET_ITEM_WSTR(home);
919 SET_ITEM_WSTRLIST(module_search_paths);
920 SET_ITEM_WSTR(executable);
Steve Dower323e7432019-06-29 14:28:59 -0700921 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100922 SET_ITEM_WSTR(prefix);
923 SET_ITEM_WSTR(base_prefix);
924 SET_ITEM_WSTR(exec_prefix);
925 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100926 SET_ITEM_INT(site_import);
927 SET_ITEM_INT(bytes_warning);
928 SET_ITEM_INT(inspect);
929 SET_ITEM_INT(interactive);
930 SET_ITEM_INT(optimization_level);
931 SET_ITEM_INT(parser_debug);
932 SET_ITEM_INT(write_bytecode);
933 SET_ITEM_INT(verbose);
934 SET_ITEM_INT(quiet);
935 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200936 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100937 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400938 SET_ITEM_WSTR(stdio_encoding);
939 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100940#ifdef MS_WINDOWS
941 SET_ITEM_INT(legacy_windows_stdio);
942#endif
943 SET_ITEM_INT(skip_source_first_line);
944 SET_ITEM_WSTR(run_command);
945 SET_ITEM_WSTR(run_module);
946 SET_ITEM_WSTR(run_filename);
947 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400948 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200949 SET_ITEM_INT(pathconfig_warnings);
950 SET_ITEM_INT(_init_main);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100951
952 return dict;
953
954fail:
955 Py_DECREF(dict);
956 return NULL;
957
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100958#undef FROM_WSTRING
959#undef SET_ITEM
960#undef SET_ITEM_INT
961#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100962#undef SET_ITEM_WSTR
963#undef SET_ITEM_WSTRLIST
964}
965
966
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100967static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200968config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200969{
Victor Stinner20004952019-03-26 02:31:11 +0100970 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200971}
972
973
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100974/* Get a copy of the environment variable as wchar_t*.
975 Return 0 on success, but *dest can be NULL.
976 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200977static PyStatus
978config_get_env_dup(PyConfig *config,
979 wchar_t **dest,
980 wchar_t *wname, char *name,
981 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200982{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200983 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100984 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200985
Victor Stinner20004952019-03-26 02:31:11 +0100986 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200987 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200988 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200989 }
990
991#ifdef MS_WINDOWS
992 const wchar_t *var = _wgetenv(wname);
993 if (!var || var[0] == '\0') {
994 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200995 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200996 }
997
Victor Stinner331a6a52019-05-27 16:39:22 +0200998 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +0200999#else
1000 const char *var = getenv(name);
1001 if (!var || var[0] == '\0') {
1002 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001003 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001004 }
1005
Victor Stinner331a6a52019-05-27 16:39:22 +02001006 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001007#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001008}
1009
1010
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001011#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001012 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001013
1014
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001015static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001016config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001017{
Victor Stinner022be022019-05-22 23:58:50 +02001018 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1019 /* Python and Isolated configuration ignore global variables */
1020 return;
1021 }
1022
Victor Stinner6c785c02018-08-01 17:56:14 +02001023#define COPY_FLAG(ATTR, VALUE) \
1024 if (config->ATTR == -1) { \
1025 config->ATTR = VALUE; \
1026 }
1027#define COPY_NOT_FLAG(ATTR, VALUE) \
1028 if (config->ATTR == -1) { \
1029 config->ATTR = !(VALUE); \
1030 }
1031
Victor Stinner20004952019-03-26 02:31:11 +01001032 COPY_FLAG(isolated, Py_IsolatedFlag);
1033 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001034 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1035 COPY_FLAG(inspect, Py_InspectFlag);
1036 COPY_FLAG(interactive, Py_InteractiveFlag);
1037 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1038 COPY_FLAG(parser_debug, Py_DebugFlag);
1039 COPY_FLAG(verbose, Py_VerboseFlag);
1040 COPY_FLAG(quiet, Py_QuietFlag);
1041#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001042 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1043#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001044 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001045
Victor Stinner6c785c02018-08-01 17:56:14 +02001046 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1047 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1048 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1049 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1050
Victor Stinner6c785c02018-08-01 17:56:14 +02001051#undef COPY_FLAG
1052#undef COPY_NOT_FLAG
1053}
1054
1055
1056/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001057static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001058config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001059{
1060#define COPY_FLAG(ATTR, VAR) \
1061 if (config->ATTR != -1) { \
1062 VAR = config->ATTR; \
1063 }
1064#define COPY_NOT_FLAG(ATTR, VAR) \
1065 if (config->ATTR != -1) { \
1066 VAR = !config->ATTR; \
1067 }
1068
Victor Stinner20004952019-03-26 02:31:11 +01001069 COPY_FLAG(isolated, Py_IsolatedFlag);
1070 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001071 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1072 COPY_FLAG(inspect, Py_InspectFlag);
1073 COPY_FLAG(interactive, Py_InteractiveFlag);
1074 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1075 COPY_FLAG(parser_debug, Py_DebugFlag);
1076 COPY_FLAG(verbose, Py_VerboseFlag);
1077 COPY_FLAG(quiet, Py_QuietFlag);
1078#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001079 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1080#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001081 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001082
Victor Stinner6c785c02018-08-01 17:56:14 +02001083 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1084 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1085 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1086 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1087
Victor Stinner6c785c02018-08-01 17:56:14 +02001088 /* Random or non-zero hash seed */
1089 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1090 config->hash_seed != 0);
1091
1092#undef COPY_FLAG
1093#undef COPY_NOT_FLAG
1094}
1095
1096
1097/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1098 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001099static PyStatus
1100config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001101{
Victor Stinner331a6a52019-05-27 16:39:22 +02001102 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001103
Victor Stinner6c785c02018-08-01 17:56:14 +02001104 /* If Py_SetProgramName() was called, use its value */
1105 const wchar_t *program_name = _Py_path_config.program_name;
1106 if (program_name != NULL) {
1107 config->program_name = _PyMem_RawWcsdup(program_name);
1108 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001109 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001110 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001111 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001112 }
1113
1114#ifdef __APPLE__
1115 /* On MacOS X, when the Python interpreter is embedded in an
1116 application bundle, it gets executed by a bootstrapping script
1117 that does os.execve() with an argv[0] that's different from the
1118 actual Python executable. This is needed to keep the Finder happy,
1119 or rather, to work around Apple's overly strict requirements of
1120 the process name. However, we still need a usable sys.executable,
1121 so the actual executable path is passed in an environment variable.
1122 See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
1123 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001124 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001125 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001126 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1127 "PYTHONEXECUTABLE environment variable");
1128 if (_PyStatus_EXCEPTION(status)) {
1129 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001130 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001131 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001132 }
1133#ifdef WITH_NEXT_FRAMEWORK
1134 else {
1135 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1136 if (pyvenv_launcher && *pyvenv_launcher) {
1137 /* Used by Mac/Tools/pythonw.c to forward
1138 * the argv0 of the stub executable
1139 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001140 status = CONFIG_SET_BYTES_STR(config,
1141 &config->program_name,
1142 pyvenv_launcher,
1143 "__PYVENV_LAUNCHER__ environment variable");
1144 if (_PyStatus_EXCEPTION(status)) {
1145 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001146 }
Miss Islington (bot)c959fa92020-03-22 11:56:26 -07001147
1148 /*
1149 * This environment variable is used to communicate between
1150 * the stub launcher and the real interpreter and isn't needed
1151 * beyond this point.
1152 *
1153 * Clean up to avoid problems when launching other programs
1154 * later on.
1155 */
1156 (void)unsetenv("__PYVENV_LAUNCHER__");
1157
Victor Stinner331a6a52019-05-27 16:39:22 +02001158 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001159 }
1160 }
1161#endif /* WITH_NEXT_FRAMEWORK */
1162#endif /* __APPLE__ */
1163
Victor Stinnerfed02e12019-05-17 11:12:09 +02001164 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001165 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001166 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1167 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1168 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001169 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001170 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001171 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001172 }
1173
Victor Stinnerfed02e12019-05-17 11:12:09 +02001174 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001175#ifdef MS_WINDOWS
1176 const wchar_t *default_program_name = L"python";
1177#else
1178 const wchar_t *default_program_name = L"python3";
1179#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001180 status = PyConfig_SetString(config, &config->program_name,
1181 default_program_name);
1182 if (_PyStatus_EXCEPTION(status)) {
1183 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001184 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001185 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001186}
1187
Victor Stinner331a6a52019-05-27 16:39:22 +02001188static PyStatus
1189config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001190{
1191 assert(config->executable == NULL);
1192
1193 /* If Py_SetProgramFullPath() was called, use its value */
1194 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1195 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001196 PyStatus status = PyConfig_SetString(config,
1197 &config->executable,
1198 program_full_path);
1199 if (_PyStatus_EXCEPTION(status)) {
1200 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001201 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001202 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001203 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001204 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001205}
Victor Stinner6c785c02018-08-01 17:56:14 +02001206
Victor Stinner4fffd382019-03-06 01:44:31 +01001207
Victor Stinner6c785c02018-08-01 17:56:14 +02001208static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001209config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001210{
Victor Stinner74f65682019-03-15 15:08:05 +01001211 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001212}
1213
1214
Victor Stinner331a6a52019-05-27 16:39:22 +02001215static PyStatus
1216config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001217{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001218 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001219
1220 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001221 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001222 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001223 PyStatus status = PyConfig_SetString(config, &config->home, home);
1224 if (_PyStatus_EXCEPTION(status)) {
1225 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001226 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001227 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001228 }
1229
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001230 return CONFIG_GET_ENV_DUP(config, &config->home,
1231 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001232}
1233
1234
Victor Stinner331a6a52019-05-27 16:39:22 +02001235static PyStatus
1236config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001237{
Victor Stinner331a6a52019-05-27 16:39:22 +02001238 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001239
1240 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1241 /* Convert a text seed to a numeric one */
1242 if (seed_text && strcmp(seed_text, "random") != 0) {
1243 const char *endptr = seed_text;
1244 unsigned long seed;
1245 errno = 0;
1246 seed = strtoul(seed_text, (char **)&endptr, 10);
1247 if (*endptr != '\0'
1248 || seed > 4294967295UL
1249 || (errno == ERANGE && seed == ULONG_MAX))
1250 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001251 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001252 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001253 }
1254 /* Use a specific hash */
1255 config->use_hash_seed = 1;
1256 config->hash_seed = seed;
1257 }
1258 else {
1259 /* Use a random hash */
1260 config->use_hash_seed = 0;
1261 config->hash_seed = 0;
1262 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001263 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001264}
1265
1266
Victor Stinner6c785c02018-08-01 17:56:14 +02001267static int
1268config_wstr_to_int(const wchar_t *wstr, int *result)
1269{
1270 const wchar_t *endptr = wstr;
1271 errno = 0;
1272 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1273 if (*endptr != '\0' || errno == ERANGE) {
1274 return -1;
1275 }
1276 if (value < INT_MIN || value > INT_MAX) {
1277 return -1;
1278 }
1279
1280 *result = (int)value;
1281 return 0;
1282}
1283
1284
Victor Stinner331a6a52019-05-27 16:39:22 +02001285static PyStatus
1286config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001287{
Victor Stinner331a6a52019-05-27 16:39:22 +02001288 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001289 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001290
Victor Stinner6c785c02018-08-01 17:56:14 +02001291 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001292 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1293 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1294 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1295 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001296
1297 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001298 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001299 if (dont_write_bytecode) {
1300 config->write_bytecode = 0;
1301 }
1302
1303 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001304 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001305 if (no_user_site_directory) {
1306 config->user_site_directory = 0;
1307 }
1308
1309 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001310 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001311 if (unbuffered_stdio) {
1312 config->buffered_stdio = 0;
1313 }
1314
1315#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001316 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001317 "PYTHONLEGACYWINDOWSSTDIO");
1318#endif
1319
Victor Stinner331a6a52019-05-27 16:39:22 +02001320 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001321 config->dump_refs = 1;
1322 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001323 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001324 config->malloc_stats = 1;
1325 }
1326
Victor Stinner331a6a52019-05-27 16:39:22 +02001327 if (config->pythonpath_env == NULL) {
1328 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1329 L"PYTHONPATH", "PYTHONPATH");
1330 if (_PyStatus_EXCEPTION(status)) {
1331 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001332 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001333 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001334
1335 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001336 status = config_init_hash_seed(config);
1337 if (_PyStatus_EXCEPTION(status)) {
1338 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001339 }
1340 }
1341
Victor Stinner331a6a52019-05-27 16:39:22 +02001342 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001343}
1344
1345
Victor Stinner331a6a52019-05-27 16:39:22 +02001346static PyStatus
1347config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001348{
1349 int nframe;
1350 int valid;
1351
Victor Stinner331a6a52019-05-27 16:39:22 +02001352 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001353 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001354 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001355 valid = (nframe >= 0);
1356 }
1357 else {
1358 valid = 0;
1359 }
1360 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001361 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001362 }
1363 config->tracemalloc = nframe;
1364 }
1365
1366 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1367 if (xoption) {
1368 const wchar_t *sep = wcschr(xoption, L'=');
1369 if (sep) {
1370 if (!config_wstr_to_int(sep + 1, &nframe)) {
1371 valid = (nframe >= 0);
1372 }
1373 else {
1374 valid = 0;
1375 }
1376 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001377 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1378 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001379 }
1380 }
1381 else {
1382 /* -X tracemalloc behaves as -X tracemalloc=1 */
1383 nframe = 1;
1384 }
1385 config->tracemalloc = nframe;
1386 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001387 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001388}
1389
1390
Victor Stinner331a6a52019-05-27 16:39:22 +02001391static PyStatus
1392config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001393{
1394 assert(config->pycache_prefix == NULL);
1395
1396 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1397 if (xoption) {
1398 const wchar_t *sep = wcschr(xoption, L'=');
1399 if (sep && wcslen(sep) > 1) {
1400 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1401 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001402 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001403 }
1404 }
1405 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001406 // PYTHONPYCACHEPREFIX env var ignored
1407 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001408 config->pycache_prefix = NULL;
1409 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001410 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001411 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001412
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001413 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1414 L"PYTHONPYCACHEPREFIX",
1415 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001416}
1417
1418
Victor Stinner331a6a52019-05-27 16:39:22 +02001419static PyStatus
1420config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001421{
1422 /* More complex options configured by env var and -X option */
1423 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001424 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001425 || config_get_xoption(config, L"faulthandler")) {
1426 config->faulthandler = 1;
1427 }
1428 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001429 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001430 || config_get_xoption(config, L"importtime")) {
1431 config->import_time = 1;
1432 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001433
Victor Stinner331a6a52019-05-27 16:39:22 +02001434 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001435 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001436 status = config_init_tracemalloc(config);
1437 if (_PyStatus_EXCEPTION(status)) {
1438 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001439 }
1440 }
1441
1442 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001443 status = config_init_pycache_prefix(config);
1444 if (_PyStatus_EXCEPTION(status)) {
1445 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001446 }
1447 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001448 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001449}
1450
1451
Victor Stinner709d23d2019-05-02 14:56:30 -04001452static const wchar_t *
Victor Stinner331a6a52019-05-27 16:39:22 +02001453config_get_stdio_errors(const PyConfig *config)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001454{
1455#ifndef MS_WINDOWS
1456 const char *loc = setlocale(LC_CTYPE, NULL);
1457 if (loc != NULL) {
1458 /* surrogateescape is the default in the legacy C and POSIX locales */
1459 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001460 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001461 }
1462
1463#ifdef PY_COERCE_C_LOCALE
1464 /* surrogateescape is the default in locale coercion target locales */
1465 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001466 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001467 }
1468#endif
1469 }
1470
Victor Stinner709d23d2019-05-02 14:56:30 -04001471 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001472#else
1473 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001474 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001475#endif
1476}
1477
1478
Victor Stinner331a6a52019-05-27 16:39:22 +02001479static PyStatus
1480config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001481{
1482#ifdef MS_WINDOWS
1483 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001484 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001485 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001486#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001487 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001488#else
1489 const char *encoding = nl_langinfo(CODESET);
1490 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001491 return _PyStatus_ERR("failed to get the locale encoding: "
1492 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001493 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001494 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001495 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001496 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001497 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001498#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001499}
1500
1501
Victor Stinner331a6a52019-05-27 16:39:22 +02001502static PyStatus
1503config_init_stdio_encoding(PyConfig *config,
1504 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001505{
Victor Stinner331a6a52019-05-27 16:39:22 +02001506 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001507
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001508 /* If Py_SetStandardStreamEncoding() have been called, use these
1509 parameters. */
1510 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001511 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1512 _Py_StandardStreamEncoding,
1513 "_Py_StandardStreamEncoding");
1514 if (_PyStatus_EXCEPTION(status)) {
1515 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001516 }
1517 }
1518
1519 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001520 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1521 _Py_StandardStreamErrors,
1522 "_Py_StandardStreamErrors");
1523 if (_PyStatus_EXCEPTION(status)) {
1524 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001525 }
1526 }
1527
1528 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001529 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001530 }
1531
1532 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001533 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001534 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001535 char *pythonioencoding = _PyMem_RawStrdup(opt);
1536 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001537 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001538 }
1539
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001540 char *errors = strchr(pythonioencoding, ':');
1541 if (errors) {
1542 *errors = '\0';
1543 errors++;
1544 if (!errors[0]) {
1545 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001546 }
1547 }
1548
1549 /* Does PYTHONIOENCODING contain an encoding? */
1550 if (pythonioencoding[0]) {
1551 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001552 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1553 pythonioencoding,
1554 "PYTHONIOENCODING environment variable");
1555 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001556 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001557 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001558 }
1559 }
1560
1561 /* If the encoding is set but not the error handler,
1562 use "strict" error handler by default.
1563 PYTHONIOENCODING=latin1 behaves as
1564 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001565 if (!errors) {
1566 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001567 }
1568 }
1569
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001570 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001571 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1572 errors,
1573 "PYTHONIOENCODING environment variable");
1574 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001575 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001576 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001577 }
1578 }
1579
1580 PyMem_RawFree(pythonioencoding);
1581 }
1582
1583 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001584 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001585 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001586 status = PyConfig_SetString(config, &config->stdio_encoding,
1587 L"utf-8");
1588 if (_PyStatus_EXCEPTION(status)) {
1589 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001590 }
1591 }
1592 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001593 status = PyConfig_SetString(config, &config->stdio_errors,
1594 L"surrogateescape");
1595 if (_PyStatus_EXCEPTION(status)) {
1596 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001597 }
1598 }
1599 }
1600
1601 /* Choose the default error handler based on the current locale. */
1602 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001603 status = config_get_locale_encoding(config, &config->stdio_encoding);
1604 if (_PyStatus_EXCEPTION(status)) {
1605 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001606 }
1607 }
1608 if (config->stdio_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001609 const wchar_t *errors = config_get_stdio_errors(config);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001610 assert(errors != NULL);
1611
Victor Stinner331a6a52019-05-27 16:39:22 +02001612 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1613 if (_PyStatus_EXCEPTION(status)) {
1614 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001615 }
1616 }
1617
Victor Stinner331a6a52019-05-27 16:39:22 +02001618 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001619}
1620
1621
Victor Stinner331a6a52019-05-27 16:39:22 +02001622static PyStatus
1623config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001624{
Victor Stinner331a6a52019-05-27 16:39:22 +02001625 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001626
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001627 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001628#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001629 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001630#else
Victor Stinnere2510952019-05-02 11:28:57 -04001631
1632#ifdef MS_WINDOWS
1633 if (preconfig->legacy_windows_fs_encoding) {
1634 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001635 status = PyConfig_SetString(config, &config->filesystem_encoding,
1636 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001637 }
1638 else
1639#endif
Victor Stinner20004952019-03-26 02:31:11 +01001640 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001641 status = PyConfig_SetString(config, &config->filesystem_encoding,
1642 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001643 }
Victor Stinnere2510952019-05-02 11:28:57 -04001644#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001645 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001646 status = PyConfig_SetString(config, &config->filesystem_encoding,
1647 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001648 }
Victor Stinnere2510952019-05-02 11:28:57 -04001649#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001650 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001651#ifdef MS_WINDOWS
1652 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001653 status = PyConfig_SetString(config, &config->filesystem_encoding,
1654 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001655#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001656 status = config_get_locale_encoding(config,
1657 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001658#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001659 }
Victor Stinnere2510952019-05-02 11:28:57 -04001660#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001661
Victor Stinner331a6a52019-05-27 16:39:22 +02001662 if (_PyStatus_EXCEPTION(status)) {
1663 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001664 }
1665 }
1666
1667 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001668 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001669#ifdef MS_WINDOWS
1670 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001671 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001672 }
1673 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001674 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001675 }
1676#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001677 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001678#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001679 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1680 if (_PyStatus_EXCEPTION(status)) {
1681 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001682 }
1683 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001684 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001685}
1686
1687
Victor Stinner331a6a52019-05-27 16:39:22 +02001688static PyStatus
1689config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001690{
Victor Stinner331a6a52019-05-27 16:39:22 +02001691 PyStatus status;
1692 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001693
Victor Stinner20004952019-03-26 02:31:11 +01001694 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001695 status = config_read_env_vars(config);
1696 if (_PyStatus_EXCEPTION(status)) {
1697 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001698 }
1699 }
1700
1701 /* -X options */
1702 if (config_get_xoption(config, L"showrefcount")) {
1703 config->show_ref_count = 1;
1704 }
1705 if (config_get_xoption(config, L"showalloccount")) {
1706 config->show_alloc_count = 1;
1707 }
1708
Victor Stinner331a6a52019-05-27 16:39:22 +02001709 status = config_read_complex_options(config);
1710 if (_PyStatus_EXCEPTION(status)) {
1711 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001712 }
1713
Victor Stinner6c785c02018-08-01 17:56:14 +02001714 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001715 status = config_init_home(config);
1716 if (_PyStatus_EXCEPTION(status)) {
1717 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001718 }
1719 }
1720
Steve Dower177a41a2018-11-17 20:41:48 -08001721 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001722 status = config_init_executable(config);
1723 if (_PyStatus_EXCEPTION(status)) {
1724 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001725 }
1726 }
1727
Victor Stinner6c785c02018-08-01 17:56:14 +02001728 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001729 status = _PyConfig_InitPathConfig(config);
1730 if (_PyStatus_EXCEPTION(status)) {
1731 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001732 }
1733 }
1734
1735 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001736 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001737 if (config->faulthandler < 0) {
1738 config->faulthandler = 1;
1739 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001740 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001741 if (config->faulthandler < 0) {
1742 config->faulthandler = 0;
1743 }
1744 if (config->tracemalloc < 0) {
1745 config->tracemalloc = 0;
1746 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001747 if (config->use_hash_seed < 0) {
1748 config->use_hash_seed = 0;
1749 config->hash_seed = 0;
1750 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001751
Victor Stinner70fead22018-08-29 13:45:34 +02001752 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001753 status = config_init_fs_encoding(config, preconfig);
1754 if (_PyStatus_EXCEPTION(status)) {
1755 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001756 }
1757 }
1758
Victor Stinner331a6a52019-05-27 16:39:22 +02001759 status = config_init_stdio_encoding(config, preconfig);
1760 if (_PyStatus_EXCEPTION(status)) {
1761 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001762 }
1763
Victor Stinner62599762019-03-15 16:03:23 +01001764 if (config->argv.length < 1) {
1765 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001766 status = PyWideStringList_Append(&config->argv, L"");
1767 if (_PyStatus_EXCEPTION(status)) {
1768 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001769 }
1770 }
Victor Stinner870b0352019-05-17 03:15:12 +02001771
1772 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001773 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1774 L"default");
1775 if (_PyStatus_EXCEPTION(status)) {
1776 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001777 }
1778 }
1779
1780 if (config->configure_c_stdio < 0) {
1781 config->configure_c_stdio = 1;
1782 }
1783
Victor Stinner331a6a52019-05-27 16:39:22 +02001784 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001785}
Victor Stinner5ed69952018-11-06 15:59:52 +01001786
1787
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001788static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001789config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001790{
1791#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1792 /* don't translate newlines (\r\n <=> \n) */
1793 _setmode(fileno(stdin), O_BINARY);
1794 _setmode(fileno(stdout), O_BINARY);
1795 _setmode(fileno(stderr), O_BINARY);
1796#endif
1797
1798 if (!config->buffered_stdio) {
1799#ifdef HAVE_SETVBUF
1800 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1801 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1802 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1803#else /* !HAVE_SETVBUF */
1804 setbuf(stdin, (char *)NULL);
1805 setbuf(stdout, (char *)NULL);
1806 setbuf(stderr, (char *)NULL);
1807#endif /* !HAVE_SETVBUF */
1808 }
1809 else if (config->interactive) {
1810#ifdef MS_WINDOWS
1811 /* Doesn't have to have line-buffered -- use unbuffered */
1812 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1813 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1814#else /* !MS_WINDOWS */
1815#ifdef HAVE_SETVBUF
1816 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1817 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1818#endif /* HAVE_SETVBUF */
1819#endif /* !MS_WINDOWS */
1820 /* Leave stderr alone - it should be unbuffered anyway. */
1821 }
1822}
1823
1824
1825/* Write the configuration:
1826
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001827 - set Py_xxx global configuration variables
1828 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001829void
Victor Stinner331a6a52019-05-27 16:39:22 +02001830_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001831{
Victor Stinner331a6a52019-05-27 16:39:22 +02001832 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001833
1834 if (config->configure_c_stdio) {
1835 config_init_stdio(config);
1836 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001837
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001838 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001839 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001840 preconfig->isolated = config->isolated;
1841 preconfig->use_environment = config->use_environment;
1842 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001843}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001844
1845
Victor Stinner331a6a52019-05-27 16:39:22 +02001846/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001847
1848static void
Victor Stinner2f549082019-03-29 15:13:46 +01001849config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001850{
Victor Stinner2f549082019-03-29 15:13:46 +01001851 FILE *f = error ? stderr : stdout;
1852
1853 fprintf(f, usage_line, program);
1854 if (error)
1855 fprintf(f, "Try `python -h' for more information.\n");
1856 else {
1857 fputs(usage_1, f);
1858 fputs(usage_2, f);
1859 fputs(usage_3, f);
1860 fprintf(f, usage_4, (wint_t)DELIM);
1861 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1862 fputs(usage_6, f);
1863 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001864}
1865
1866
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001867/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001868static PyStatus
1869config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001870 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001871{
Victor Stinner331a6a52019-05-27 16:39:22 +02001872 PyStatus status;
1873 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001874 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001875 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001876
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001877 _PyOS_ResetGetOpt();
1878 do {
1879 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001880 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001881 if (c == EOF) {
1882 break;
1883 }
1884
1885 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001886 if (config->run_command == NULL) {
1887 /* -c is the last option; following arguments
1888 that look like options are left for the
1889 command to interpret. */
1890 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1891 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1892 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001893 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001894 }
1895 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1896 command[len - 2] = '\n';
1897 command[len - 1] = 0;
1898 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001899 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001900 break;
1901 }
1902
1903 if (c == 'm') {
1904 /* -m is the last option; following arguments
1905 that look like options are left for the
1906 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001907 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001908 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1909 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001910 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001911 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001912 }
1913 break;
1914 }
1915
1916 switch (c) {
1917 case 0:
1918 // Handle long option.
1919 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001920 if (wcscmp(_PyOS_optarg, L"always") == 0
1921 || wcscmp(_PyOS_optarg, L"never") == 0
1922 || wcscmp(_PyOS_optarg, L"default") == 0)
1923 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001924 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1925 _PyOS_optarg);
1926 if (_PyStatus_EXCEPTION(status)) {
1927 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001928 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001929 } else {
1930 fprintf(stderr, "--check-hash-based-pycs must be one of "
1931 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001932 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001933 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001934 }
1935 break;
1936
1937 case 'b':
1938 config->bytes_warning++;
1939 break;
1940
1941 case 'd':
1942 config->parser_debug++;
1943 break;
1944
1945 case 'i':
1946 config->inspect++;
1947 config->interactive++;
1948 break;
1949
Victor Stinner6dcb5422019-03-05 02:44:12 +01001950 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001951 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001952 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001953 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001954 break;
1955
1956 /* case 'J': reserved for Jython */
1957
1958 case 'O':
1959 config->optimization_level++;
1960 break;
1961
1962 case 'B':
1963 config->write_bytecode = 0;
1964 break;
1965
1966 case 's':
1967 config->user_site_directory = 0;
1968 break;
1969
1970 case 'S':
1971 config->site_import = 0;
1972 break;
1973
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001974 case 't':
1975 /* ignored for backwards compatibility */
1976 break;
1977
1978 case 'u':
1979 config->buffered_stdio = 0;
1980 break;
1981
1982 case 'v':
1983 config->verbose++;
1984 break;
1985
1986 case 'x':
1987 config->skip_source_first_line = 1;
1988 break;
1989
1990 case 'h':
1991 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001992 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001993 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001994
1995 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01001996 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001997 break;
1998
1999 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002000 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2001 if (_PyStatus_EXCEPTION(status)) {
2002 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002003 }
2004 break;
2005
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002006 case 'q':
2007 config->quiet++;
2008 break;
2009
2010 case 'R':
2011 config->use_hash_seed = 0;
2012 break;
2013
2014 /* This space reserved for other options */
2015
2016 default:
2017 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002018 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002019 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002020 }
2021 } while (1);
2022
Victor Stinner2f549082019-03-29 15:13:46 +01002023 if (print_version) {
2024 printf("Python %s\n",
2025 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002026 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002027 }
2028
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002029 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002030 && _PyOS_optind < argv->length
2031 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002032 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002033 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002034 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002035 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002036 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002037 }
2038 }
2039
2040 if (config->run_command != NULL || config->run_module != NULL) {
2041 /* Backup _PyOS_optind */
2042 _PyOS_optind--;
2043 }
2044
Victor Stinnerae239f62019-05-16 17:02:56 +02002045 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002046
Victor Stinner331a6a52019-05-27 16:39:22 +02002047 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002048}
2049
2050
2051#ifdef MS_WINDOWS
2052# define WCSTOK wcstok_s
2053#else
2054# define WCSTOK wcstok
2055#endif
2056
2057/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002058static PyStatus
2059config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002060{
Victor Stinner331a6a52019-05-27 16:39:22 +02002061 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002062 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2063 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002064 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002065 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002066 if (_PyStatus_EXCEPTION(status)) {
2067 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002068 }
2069
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002070 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002071 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002072 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002073 }
2074
2075
2076 wchar_t *warning, *context = NULL;
2077 for (warning = WCSTOK(env, L",", &context);
2078 warning != NULL;
2079 warning = WCSTOK(NULL, L",", &context))
2080 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002081 status = PyWideStringList_Append(warnoptions, warning);
2082 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002083 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002084 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002085 }
2086 }
2087 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002088 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002089}
2090
2091
Victor Stinner331a6a52019-05-27 16:39:22 +02002092static PyStatus
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002093warnoptions_append(PyConfig *config, PyWideStringList *options,
2094 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002095{
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002096 /* config_init_warnoptions() add existing config warnoptions at the end:
2097 ensure that the new option is not already present in this list to
2098 prevent change the options order whne config_init_warnoptions() is
2099 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002100 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002101 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002102 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002103 }
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002104 if (_PyWideStringList_Find(options, option)) {
2105 /* Already present: do nothing */
2106 return _PyStatus_OK();
2107 }
2108 return PyWideStringList_Append(options, option);
2109}
2110
2111
2112static PyStatus
2113warnoptions_extend(PyConfig *config, PyWideStringList *options,
2114 const PyWideStringList *options2)
2115{
2116 const Py_ssize_t len = options2->length;
2117 wchar_t *const *items = options2->items;
2118
2119 for (Py_ssize_t i = 0; i < len; i++) {
2120 PyStatus status = warnoptions_append(config, options, items[i]);
2121 if (_PyStatus_EXCEPTION(status)) {
2122 return status;
2123 }
2124 }
2125 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002126}
2127
2128
Victor Stinner331a6a52019-05-27 16:39:22 +02002129static PyStatus
2130config_init_warnoptions(PyConfig *config,
2131 const PyWideStringList *cmdline_warnoptions,
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002132 const PyWideStringList *env_warnoptions,
2133 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002134{
Victor Stinner331a6a52019-05-27 16:39:22 +02002135 PyStatus status;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002136 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002137
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002138 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002139 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002140 * - any implicit filters added by _warnings.c/warnings.py
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002141 * - PyConfig.dev_mode: "default" filter
2142 * - PYTHONWARNINGS environment variable
2143 * - '-W' command line options
2144 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2145 * "default::BytesWarning" or "error::BytesWarning" filter
2146 * - early PySys_AddWarnOption() calls
2147 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002148 *
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002149 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2150 * module works on the basis of "the most recently added filter will be
2151 * checked first", we add the lowest precedence entries first so that later
2152 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002153 */
2154
Victor Stinner20004952019-03-26 02:31:11 +01002155 if (config->dev_mode) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002156 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002157 if (_PyStatus_EXCEPTION(status)) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002158 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002159 }
2160 }
2161
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002162 status = warnoptions_extend(config, &options, env_warnoptions);
2163 if (_PyStatus_EXCEPTION(status)) {
2164 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002165 }
2166
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002167 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2168 if (_PyStatus_EXCEPTION(status)) {
2169 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002170 }
2171
2172 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2173 * don't even try to emit a warning, so we skip setting the filter in that
2174 * case.
2175 */
2176 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002177 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002178 if (config->bytes_warning> 1) {
2179 filter = L"error::BytesWarning";
2180 }
2181 else {
2182 filter = L"default::BytesWarning";
2183 }
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002184 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002185 if (_PyStatus_EXCEPTION(status)) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002186 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002187 }
2188 }
Victor Stinneraf84a882019-08-23 21:16:51 +02002189
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002190 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinneraf84a882019-08-23 21:16:51 +02002191 if (_PyStatus_EXCEPTION(status)) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002192 goto error;
Victor Stinneraf84a882019-08-23 21:16:51 +02002193 }
2194
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002195 /* Always add all PyConfig.warnoptions options */
2196 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2197 if (_PyStatus_EXCEPTION(status)) {
2198 goto error;
2199 }
2200
2201 _PyWideStringList_Clear(&config->warnoptions);
2202 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002203 return _PyStatus_OK();
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002204
2205error:
2206 _PyWideStringList_Clear(&options);
2207 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002208}
2209
2210
Victor Stinner331a6a52019-05-27 16:39:22 +02002211static PyStatus
2212config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002213{
Victor Stinner331a6a52019-05-27 16:39:22 +02002214 const PyWideStringList *cmdline_argv = &config->argv;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002215 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002216
Victor Stinner74f65682019-03-15 15:08:05 +01002217 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002218 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002219 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002220 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2221 if (_PyStatus_EXCEPTION(status)) {
2222 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002223 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002224 }
2225 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002226 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002227 slice.length = cmdline_argv->length - opt_index;
2228 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002229 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2230 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002231 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002232 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002233 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002234
2235 wchar_t *arg0 = NULL;
2236 if (config->run_command != NULL) {
2237 /* Force sys.argv[0] = '-c' */
2238 arg0 = L"-c";
2239 }
2240 else if (config->run_module != NULL) {
2241 /* Force sys.argv[0] = '-m'*/
2242 arg0 = L"-m";
2243 }
2244 if (arg0 != NULL) {
2245 arg0 = _PyMem_RawWcsdup(arg0);
2246 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002247 _PyWideStringList_Clear(&config_argv);
2248 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002249 }
2250
Victor Stinnerfa153762019-03-20 04:25:38 +01002251 PyMem_RawFree(config_argv.items[0]);
2252 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002253 }
2254
Victor Stinner331a6a52019-05-27 16:39:22 +02002255 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002256 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002257 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002258}
2259
2260
Victor Stinner331a6a52019-05-27 16:39:22 +02002261static PyStatus
2262core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002263{
Victor Stinner331a6a52019-05-27 16:39:22 +02002264 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002265
Victor Stinnercab5d072019-05-17 19:01:14 +02002266 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002267 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2268 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002269 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002270 }
2271
Victor Stinner331a6a52019-05-27 16:39:22 +02002272 PyPreConfig preconfig;
Victor Stinner6e128382019-09-28 04:50:43 +02002273
2274 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2275 if (_PyStatus_EXCEPTION(status)) {
2276 return status;
2277 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002278
Victor Stinner331a6a52019-05-27 16:39:22 +02002279 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002280
Victor Stinner331a6a52019-05-27 16:39:22 +02002281 status = _PyPreCmdline_Read(precmdline, &preconfig);
2282 if (_PyStatus_EXCEPTION(status)) {
2283 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002284 }
2285
Victor Stinner331a6a52019-05-27 16:39:22 +02002286 status = _PyPreCmdline_SetConfig(precmdline, config);
2287 if (_PyStatus_EXCEPTION(status)) {
2288 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002289 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002290 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002291}
2292
2293
Victor Stinner331a6a52019-05-27 16:39:22 +02002294static PyStatus
2295config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002296{
Victor Stinner331a6a52019-05-27 16:39:22 +02002297 PyStatus status;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002298 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2299 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2300 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002301
Victor Stinnerae239f62019-05-16 17:02:56 +02002302 if (config->parse_argv < 0) {
2303 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002304 }
Victor Stinner870b0352019-05-17 03:15:12 +02002305
Victor Stinnerfed02e12019-05-17 11:12:09 +02002306 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002307 status = config_init_program_name(config);
2308 if (_PyStatus_EXCEPTION(status)) {
2309 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002310 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002311 }
Victor Stinner2f549082019-03-29 15:13:46 +01002312
Victor Stinnerae239f62019-05-16 17:02:56 +02002313 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002314 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002315 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2316 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002317 goto done;
2318 }
2319
Victor Stinner331a6a52019-05-27 16:39:22 +02002320 status = config_update_argv(config, opt_index);
2321 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002322 goto done;
2323 }
Victor Stinner2f549082019-03-29 15:13:46 +01002324 }
2325
Victor Stinner2f549082019-03-29 15:13:46 +01002326 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002327 status = config_init_env_warnoptions(config, &env_warnoptions);
2328 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002329 goto done;
2330 }
2331 }
2332
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002333 /* Handle early PySys_AddWarnOption() calls */
2334 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2335 if (_PyStatus_EXCEPTION(status)) {
2336 goto done;
2337 }
2338
Victor Stinner331a6a52019-05-27 16:39:22 +02002339 status = config_init_warnoptions(config,
Victor Stinneraf84a882019-08-23 21:16:51 +02002340 &cmdline_warnoptions,
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002341 &env_warnoptions,
2342 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002343 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002344 goto done;
2345 }
2346
Victor Stinner331a6a52019-05-27 16:39:22 +02002347 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002348
2349done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002350 _PyWideStringList_Clear(&cmdline_warnoptions);
2351 _PyWideStringList_Clear(&env_warnoptions);
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002352 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002353 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002354}
2355
2356
Victor Stinner331a6a52019-05-27 16:39:22 +02002357PyStatus
2358_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002359{
Victor Stinner331a6a52019-05-27 16:39:22 +02002360 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2361 if (_PyStatus_EXCEPTION(status)) {
2362 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002363 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002364
Victor Stinner5f38b842019-05-01 02:30:12 +02002365 return _PyArgv_AsWstrList(args, &config->argv);
2366}
2367
2368
Victor Stinner70005ac2019-05-02 15:25:34 -04002369/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2370 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002371PyStatus
2372PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002373{
2374 _PyArgv args = {
2375 .argc = argc,
2376 .use_bytes_argv = 1,
2377 .bytes_argv = argv,
2378 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002379 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002380}
2381
2382
Victor Stinner331a6a52019-05-27 16:39:22 +02002383PyStatus
2384PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002385{
2386 _PyArgv args = {
2387 .argc = argc,
2388 .use_bytes_argv = 0,
2389 .bytes_argv = NULL,
2390 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002391 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002392}
2393
2394
Miss Islington (bot)96f581c2019-07-01 10:39:58 -07002395PyStatus
2396PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2397 Py_ssize_t length, wchar_t **items)
2398{
2399 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2400 if (_PyStatus_EXCEPTION(status)) {
2401 return status;
2402 }
2403
2404 PyWideStringList list2 = {.length = length, .items = items};
2405 if (_PyWideStringList_Copy(list, &list2) < 0) {
2406 return _PyStatus_NO_MEMORY();
2407 }
2408 return _PyStatus_OK();
2409}
2410
2411
Victor Stinner331a6a52019-05-27 16:39:22 +02002412/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002413
2414 * Command line arguments
2415 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002416 * Py_xxx global configuration variables
2417
2418 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002419PyStatus
2420PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002421{
Victor Stinner331a6a52019-05-27 16:39:22 +02002422 PyStatus status;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002423 PyWideStringList orig_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002424
Victor Stinner331a6a52019-05-27 16:39:22 +02002425 status = _Py_PreInitializeFromConfig(config, NULL);
2426 if (_PyStatus_EXCEPTION(status)) {
2427 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002428 }
2429
Victor Stinner331a6a52019-05-27 16:39:22 +02002430 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002431
Victor Stinner331a6a52019-05-27 16:39:22 +02002432 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2433 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002434 }
2435
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002436 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002437 status = core_read_precmdline(config, &precmdline);
2438 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002439 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002440 }
2441
Victor Stinner870b0352019-05-17 03:15:12 +02002442 assert(config->isolated >= 0);
2443 if (config->isolated) {
2444 config->use_environment = 0;
2445 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002446 }
2447
Victor Stinner331a6a52019-05-27 16:39:22 +02002448 status = config_read_cmdline(config);
2449 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002450 goto done;
2451 }
2452
Victor Stinneraf84a882019-08-23 21:16:51 +02002453 /* Handle early PySys_AddXOption() calls */
2454 status = _PySys_ReadPreinitXOptions(config);
2455 if (_PyStatus_EXCEPTION(status)) {
2456 goto done;
2457 }
2458
Victor Stinner331a6a52019-05-27 16:39:22 +02002459 status = config_read(config);
2460 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002461 goto done;
2462 }
2463
Victor Stinnercab5d072019-05-17 19:01:14 +02002464 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002465 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002466 goto done;
2467 }
2468
2469 /* Check config consistency */
2470 assert(config->isolated >= 0);
2471 assert(config->use_environment >= 0);
2472 assert(config->dev_mode >= 0);
2473 assert(config->install_signal_handlers >= 0);
2474 assert(config->use_hash_seed >= 0);
2475 assert(config->faulthandler >= 0);
2476 assert(config->tracemalloc >= 0);
2477 assert(config->site_import >= 0);
2478 assert(config->bytes_warning >= 0);
2479 assert(config->inspect >= 0);
2480 assert(config->interactive >= 0);
2481 assert(config->optimization_level >= 0);
2482 assert(config->parser_debug >= 0);
2483 assert(config->write_bytecode >= 0);
2484 assert(config->verbose >= 0);
2485 assert(config->quiet >= 0);
2486 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002487 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002488 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002489 assert(config->buffered_stdio >= 0);
2490 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002491 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002492 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2493 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002494 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2495 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2496 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002497 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002498 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002499 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002500 assert(config->executable != NULL);
Steve Dower323e7432019-06-29 14:28:59 -07002501 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002502 assert(config->prefix != NULL);
2503 assert(config->base_prefix != NULL);
2504 assert(config->exec_prefix != NULL);
2505 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002506 }
2507 assert(config->filesystem_encoding != NULL);
2508 assert(config->filesystem_errors != NULL);
2509 assert(config->stdio_encoding != NULL);
2510 assert(config->stdio_errors != NULL);
2511#ifdef MS_WINDOWS
2512 assert(config->legacy_windows_stdio >= 0);
2513#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002514 /* -c and -m options are exclusive */
2515 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002516 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002517 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002518 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002519
Victor Stinner331a6a52019-05-27 16:39:22 +02002520 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002521
2522done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002523 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002524 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002525 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002526}
Victor Stinner1075d162019-03-25 23:19:57 +01002527
2528
2529PyObject*
2530_Py_GetConfigsAsDict(void)
2531{
Victor Stinner331a6a52019-05-27 16:39:22 +02002532 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002533 PyObject *dict = NULL;
2534
Victor Stinner331a6a52019-05-27 16:39:22 +02002535 result = PyDict_New();
2536 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002537 goto error;
2538 }
2539
Victor Stinner331a6a52019-05-27 16:39:22 +02002540 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002541 dict = _Py_GetGlobalVariablesAsDict();
2542 if (dict == NULL) {
2543 goto error;
2544 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002545 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002546 goto error;
2547 }
2548 Py_CLEAR(dict);
2549
2550 /* pre config */
2551 PyInterpreterState *interp = _PyInterpreterState_Get();
Victor Stinner331a6a52019-05-27 16:39:22 +02002552 const PyPreConfig *pre_config = &_PyRuntime.preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002553 dict = _PyPreConfig_AsDict(pre_config);
2554 if (dict == NULL) {
2555 goto error;
2556 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002557 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002558 goto error;
2559 }
2560 Py_CLEAR(dict);
2561
2562 /* core config */
Victor Stinner331a6a52019-05-27 16:39:22 +02002563 const PyConfig *config = &interp->config;
2564 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002565 if (dict == NULL) {
2566 goto error;
2567 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002568 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002569 goto error;
2570 }
2571 Py_CLEAR(dict);
2572
Victor Stinner331a6a52019-05-27 16:39:22 +02002573 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002574
2575error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002576 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002577 Py_XDECREF(dict);
2578 return NULL;
2579}
Victor Stinnerc5c64252019-09-23 15:59:00 +02002580
2581
2582static void
2583init_dump_ascii_wstr(const wchar_t *str)
2584{
2585 if (str == NULL) {
2586 PySys_WriteStderr("(not set)");
2587 return;
2588 }
2589
2590 PySys_WriteStderr("'");
2591 for (; *str != L'\0'; str++) {
2592 wchar_t ch = *str;
2593 if (ch == L'\'') {
2594 PySys_WriteStderr("\\'");
2595 } else if (0x20 <= ch && ch < 0x7f) {
2596 PySys_WriteStderr("%lc", ch);
2597 }
2598 else if (ch <= 0xff) {
2599 PySys_WriteStderr("\\x%02x", ch);
2600 }
2601#if SIZEOF_WCHAR_T > 2
2602 else if (ch > 0xffff) {
2603 PySys_WriteStderr("\\U%08x", ch);
2604 }
2605#endif
2606 else {
2607 PySys_WriteStderr("\\u%04x", ch);
2608 }
2609 }
2610 PySys_WriteStderr("'");
2611}
2612
2613
2614/* Dump the Python path configuration into sys.stderr */
2615void
2616_Py_DumpPathConfig(PyThreadState *tstate)
2617{
2618 PyObject *exc_type, *exc_value, *exc_tb;
2619 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2620
2621 PySys_WriteStderr("Python path configuration:\n");
2622
2623#define DUMP_CONFIG(NAME, FIELD) \
2624 do { \
2625 PySys_WriteStderr(" " NAME " = "); \
2626 init_dump_ascii_wstr(config->FIELD); \
2627 PySys_WriteStderr("\n"); \
2628 } while (0)
2629
2630 PyConfig *config = &tstate->interp->config;
2631 DUMP_CONFIG("PYTHONHOME", home);
2632 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2633 DUMP_CONFIG("program name", program_name);
2634 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2635 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2636 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2637 PySys_WriteStderr(" import site = %i\n", config->site_import);
2638#undef DUMP_CONFIG
2639
2640#define DUMP_SYS(NAME) \
2641 do { \
2642 obj = PySys_GetObject(#NAME); \
2643 PySys_FormatStderr(" sys.%s = ", #NAME); \
2644 if (obj != NULL) { \
2645 PySys_FormatStderr("%A", obj); \
2646 } \
2647 else { \
2648 PySys_WriteStderr("(not set)"); \
2649 } \
2650 PySys_FormatStderr("\n"); \
2651 } while (0)
2652
2653 PyObject *obj;
2654 DUMP_SYS(_base_executable);
2655 DUMP_SYS(base_prefix);
2656 DUMP_SYS(base_exec_prefix);
2657 DUMP_SYS(executable);
2658 DUMP_SYS(prefix);
2659 DUMP_SYS(exec_prefix);
2660#undef DUMP_SYS
2661
2662 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2663 if (sys_path != NULL && PyList_Check(sys_path)) {
2664 PySys_WriteStderr(" sys.path = [\n");
2665 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2666 for (Py_ssize_t i=0; i < len; i++) {
2667 PyObject *path = PyList_GET_ITEM(sys_path, i);
2668 PySys_FormatStderr(" %A,\n", path);
2669 }
2670 PySys_WriteStderr(" ]\n");
2671 }
2672
2673 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2674}