blob: a30fdd1bab95423820671364c00e8d601ff50da7 [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\
66-X opt : set implementation-specific option\n\
67--check-hash-based-pycs always|default|never:\n\
68 control how Python invalidates hash-based .pyc files\n\
69";
70static const char usage_4[] = "\
71file : program read from script file\n\
72- : program read from stdin (default; interactive mode if a tty)\n\
73arg ...: arguments passed to program in sys.argv[1:]\n\n\
74Other environment variables:\n\
75PYTHONSTARTUP: file executed on interactive startup (no default)\n\
76PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
77 default module search path. The result is sys.path.\n\
78";
79static const char usage_5[] =
80"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
81" The default module search path uses %s.\n"
82"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
Miss Islington (bot)4a5db782019-12-14 02:38:35 -080083"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +010084"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
85"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
86static const char usage_6[] =
87"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Miss Islington (bot)076d0b92019-08-24 03:19:51 -070088" to seed the hashes of str and bytes objects. It can also be set to an\n"
89" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +010090" predictable seed.\n"
91"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
92" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
93" hooks.\n"
94"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
95" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
96" locale coercion and locale compatibility warnings on stderr.\n"
97"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
98" debugger. It can be set to the callable of your debugger of choice.\n"
99"PYTHONDEVMODE: enable the development mode.\n"
100"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
101
102#if defined(MS_WINDOWS)
103# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
104#else
105# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
106#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200107
108
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100109/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200110
Victor Stinner6c785c02018-08-01 17:56:14 +0200111/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200112 stdin and stdout error handler to "surrogateescape". */
113int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200114int Py_DebugFlag = 0; /* Needed by parser.c */
115int Py_VerboseFlag = 0; /* Needed by import.c */
116int Py_QuietFlag = 0; /* Needed by sysmodule.c */
117int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
118int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
119int Py_OptimizeFlag = 0; /* Needed by compile.c */
120int Py_NoSiteFlag = 0; /* Suppress 'import site' */
121int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
122int Py_FrozenFlag = 0; /* Needed by getpath.c */
123int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
124int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
125int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
126int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
127int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
128int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
129#ifdef MS_WINDOWS
130int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
131int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
132#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200133
134
Victor Stinner1075d162019-03-25 23:19:57 +0100135static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100136_Py_GetGlobalVariablesAsDict(void)
137{
138 PyObject *dict, *obj;
139
140 dict = PyDict_New();
141 if (dict == NULL) {
142 return NULL;
143 }
144
145#define SET_ITEM(KEY, EXPR) \
146 do { \
147 obj = (EXPR); \
148 if (obj == NULL) { \
149 return NULL; \
150 } \
151 int res = PyDict_SetItemString(dict, (KEY), obj); \
152 Py_DECREF(obj); \
153 if (res < 0) { \
154 goto fail; \
155 } \
156 } while (0)
157#define SET_ITEM_INT(VAR) \
158 SET_ITEM(#VAR, PyLong_FromLong(VAR))
159#define FROM_STRING(STR) \
160 ((STR != NULL) ? \
161 PyUnicode_FromString(STR) \
162 : (Py_INCREF(Py_None), Py_None))
163#define SET_ITEM_STR(VAR) \
164 SET_ITEM(#VAR, FROM_STRING(VAR))
165
166 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
167 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
168 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
169 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
170
171 SET_ITEM_INT(Py_UTF8Mode);
172 SET_ITEM_INT(Py_DebugFlag);
173 SET_ITEM_INT(Py_VerboseFlag);
174 SET_ITEM_INT(Py_QuietFlag);
175 SET_ITEM_INT(Py_InteractiveFlag);
176 SET_ITEM_INT(Py_InspectFlag);
177
178 SET_ITEM_INT(Py_OptimizeFlag);
179 SET_ITEM_INT(Py_NoSiteFlag);
180 SET_ITEM_INT(Py_BytesWarningFlag);
181 SET_ITEM_INT(Py_FrozenFlag);
182 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
183 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
184 SET_ITEM_INT(Py_NoUserSiteDirectory);
185 SET_ITEM_INT(Py_UnbufferedStdioFlag);
186 SET_ITEM_INT(Py_HashRandomizationFlag);
187 SET_ITEM_INT(Py_IsolatedFlag);
188
189#ifdef MS_WINDOWS
190 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
191 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
192#endif
193
194 return dict;
195
196fail:
197 Py_DECREF(dict);
198 return NULL;
199
200#undef FROM_STRING
201#undef SET_ITEM
202#undef SET_ITEM_INT
203#undef SET_ITEM_STR
204}
205
206
Victor Stinner331a6a52019-05-27 16:39:22 +0200207/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200208
Victor Stinner331a6a52019-05-27 16:39:22 +0200209PyStatus PyStatus_Ok(void)
210{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200211
Victor Stinner331a6a52019-05-27 16:39:22 +0200212PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200213{
Victor Stinner331a6a52019-05-27 16:39:22 +0200214 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner871ff772019-05-17 23:54:00 +0200215 .err_msg = err_msg};
216}
217
Victor Stinner331a6a52019-05-27 16:39:22 +0200218PyStatus PyStatus_NoMemory(void)
219{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200220
Victor Stinner331a6a52019-05-27 16:39:22 +0200221PyStatus PyStatus_Exit(int exitcode)
222{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200223
224
Victor Stinner331a6a52019-05-27 16:39:22 +0200225int PyStatus_IsError(PyStatus status)
226{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200227
Victor Stinner331a6a52019-05-27 16:39:22 +0200228int PyStatus_IsExit(PyStatus status)
229{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200230
Victor Stinner331a6a52019-05-27 16:39:22 +0200231int PyStatus_Exception(PyStatus status)
232{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200233
234
Victor Stinner331a6a52019-05-27 16:39:22 +0200235/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100236
237#ifndef NDEBUG
238int
Victor Stinner331a6a52019-05-27 16:39:22 +0200239_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100240{
241 assert(list->length >= 0);
242 if (list->length != 0) {
243 assert(list->items != NULL);
244 }
245 for (Py_ssize_t i = 0; i < list->length; i++) {
246 assert(list->items[i] != NULL);
247 }
248 return 1;
249}
250#endif /* Py_DEBUG */
251
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100252
Victor Stinner6c785c02018-08-01 17:56:14 +0200253void
Victor Stinner331a6a52019-05-27 16:39:22 +0200254_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200255{
Victor Stinner331a6a52019-05-27 16:39:22 +0200256 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100257 for (Py_ssize_t i=0; i < list->length; i++) {
258 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200259 }
Victor Stinner74f65682019-03-15 15:08:05 +0100260 PyMem_RawFree(list->items);
261 list->length = 0;
262 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200263}
264
265
Victor Stinner74f65682019-03-15 15:08:05 +0100266int
Victor Stinner331a6a52019-05-27 16:39:22 +0200267_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200268{
Victor Stinner331a6a52019-05-27 16:39:22 +0200269 assert(_PyWideStringList_CheckConsistency(list));
270 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100271
272 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200273 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100274 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300275 }
Victor Stinner74f65682019-03-15 15:08:05 +0100276
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -0700277 PyWideStringList copy = _PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100278
279 size_t size = list2->length * sizeof(list2->items[0]);
280 copy.items = PyMem_RawMalloc(size);
281 if (copy.items == NULL) {
282 return -1;
283 }
284
285 for (Py_ssize_t i=0; i < list2->length; i++) {
286 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
287 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200288 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100289 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200290 }
Victor Stinner74f65682019-03-15 15:08:05 +0100291 copy.items[i] = item;
292 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200293 }
Victor Stinner74f65682019-03-15 15:08:05 +0100294
Victor Stinner331a6a52019-05-27 16:39:22 +0200295 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100296 *list = copy;
297 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200298}
299
300
Victor Stinner331a6a52019-05-27 16:39:22 +0200301PyStatus
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700302PyWideStringList_Insert(PyWideStringList *list,
303 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100304{
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700305 Py_ssize_t len = list->length;
306 if (len == PY_SSIZE_T_MAX) {
Kyle Stanley24b5b362019-07-21 22:48:45 -0400307 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200308 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100309 }
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700310 if (index < 0) {
311 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
312 }
313 if (index > len) {
314 index = len;
315 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100316
Victor Stinner74f65682019-03-15 15:08:05 +0100317 wchar_t *item2 = _PyMem_RawWcsdup(item);
318 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200319 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100320 }
Victor Stinner74f65682019-03-15 15:08:05 +0100321
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700322 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100323 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
324 if (items2 == NULL) {
325 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200326 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100327 }
328
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700329 if (index < len) {
330 memmove(&items2[index + 1],
331 &items2[index],
332 (len - index) * sizeof(items2[0]));
333 }
334
335 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100336 list->items = items2;
337 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200338 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100339}
340
341
Victor Stinner331a6a52019-05-27 16:39:22 +0200342PyStatus
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700343PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
344{
345 return PyWideStringList_Insert(list, list->length, item);
346}
347
348
349PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200350_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100351{
352 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200353 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
354 if (_PyStatus_EXCEPTION(status)) {
355 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100356 }
357 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200358 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100359}
360
361
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100362static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200363_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100364{
365 for (Py_ssize_t i = 0; i < list->length; i++) {
366 if (wcscmp(list->items[i], item) == 0) {
367 return 1;
368 }
369 }
370 return 0;
371}
372
373
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100374PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200375_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100376{
Victor Stinner331a6a52019-05-27 16:39:22 +0200377 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100378
Victor Stinner74f65682019-03-15 15:08:05 +0100379 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100380 if (pylist == NULL) {
381 return NULL;
382 }
383
Victor Stinner74f65682019-03-15 15:08:05 +0100384 for (Py_ssize_t i = 0; i < list->length; i++) {
385 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
386 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100387 Py_DECREF(pylist);
388 return NULL;
389 }
Victor Stinner74f65682019-03-15 15:08:05 +0100390 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100391 }
392 return pylist;
393}
394
395
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100396/* --- Py_SetStandardStreamEncoding() ----------------------------- */
397
Victor Stinner124b9eb2018-08-29 01:29:06 +0200398/* Helper to allow an embedding application to override the normal
399 * mechanism that attempts to figure out an appropriate IO encoding
400 */
401
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200402static char *_Py_StandardStreamEncoding = NULL;
403static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200404
405int
406Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
407{
408 if (Py_IsInitialized()) {
409 /* This is too late to have any effect */
410 return -1;
411 }
412
413 int res = 0;
414
415 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
416 but Py_Initialize() can change the allocator. Use a known allocator
417 to be able to release the memory later. */
418 PyMemAllocatorEx old_alloc;
419 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
420
421 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
422 * initialised yet.
423 *
424 * However, the raw memory allocators are initialised appropriately
425 * as C static variables, so _PyMem_RawStrdup is OK even though
426 * Py_Initialize hasn't been called yet.
427 */
428 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200429 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200430 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
431 if (!_Py_StandardStreamEncoding) {
432 res = -2;
433 goto done;
434 }
435 }
436 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200437 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200438 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
439 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200440 PyMem_RawFree(_Py_StandardStreamEncoding);
441 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200442 res = -3;
443 goto done;
444 }
445 }
446#ifdef MS_WINDOWS
447 if (_Py_StandardStreamEncoding) {
448 /* Overriding the stream encoding implies legacy streams */
449 Py_LegacyWindowsStdioFlag = 1;
450 }
451#endif
452
453done:
454 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
455
456 return res;
457}
458
459
460void
461_Py_ClearStandardStreamEncoding(void)
462{
463 /* Use the same allocator than Py_SetStandardStreamEncoding() */
464 PyMemAllocatorEx old_alloc;
465 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
466
467 /* We won't need them anymore. */
468 if (_Py_StandardStreamEncoding) {
469 PyMem_RawFree(_Py_StandardStreamEncoding);
470 _Py_StandardStreamEncoding = NULL;
471 }
472 if (_Py_StandardStreamErrors) {
473 PyMem_RawFree(_Py_StandardStreamErrors);
474 _Py_StandardStreamErrors = NULL;
475 }
476
477 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
478}
479
480
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100481/* --- Py_GetArgcArgv() ------------------------------------------- */
482
483/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200484static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100485
486
487void
488_Py_ClearArgcArgv(void)
489{
490 PyMemAllocatorEx old_alloc;
491 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
492
Victor Stinner331a6a52019-05-27 16:39:22 +0200493 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100494
495 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
496}
497
498
Victor Stinner4fffd382019-03-06 01:44:31 +0100499static int
Victor Stinner74f65682019-03-15 15:08:05 +0100500_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100501{
Victor Stinner331a6a52019-05-27 16:39:22 +0200502 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100503 int res;
504
505 PyMemAllocatorEx old_alloc;
506 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
507
Victor Stinner331a6a52019-05-27 16:39:22 +0200508 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100509
510 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
511 return res;
512}
513
514
515/* Make the *original* argc/argv available to other modules.
516 This is rare, but it is needed by the secureware extension. */
517void
518Py_GetArgcArgv(int *argc, wchar_t ***argv)
519{
Victor Stinner74f65682019-03-15 15:08:05 +0100520 *argc = (int)orig_argv.length;
521 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100522}
523
524
Victor Stinner331a6a52019-05-27 16:39:22 +0200525/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100526
527#define DECODE_LOCALE_ERR(NAME, LEN) \
528 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200529 ? _PyStatus_ERR("cannot decode " NAME) \
530 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100531
Victor Stinner6e128382019-09-28 04:50:43 +0200532
Victor Stinner6c785c02018-08-01 17:56:14 +0200533/* Free memory allocated in config, but don't clear all attributes */
534void
Victor Stinner331a6a52019-05-27 16:39:22 +0200535PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200536{
537#define CLEAR(ATTR) \
538 do { \
539 PyMem_RawFree(ATTR); \
540 ATTR = NULL; \
541 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200542
543 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200544 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200545 CLEAR(config->home);
546 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200547
Victor Stinner331a6a52019-05-27 16:39:22 +0200548 _PyWideStringList_Clear(&config->argv);
549 _PyWideStringList_Clear(&config->warnoptions);
550 _PyWideStringList_Clear(&config->xoptions);
551 _PyWideStringList_Clear(&config->module_search_paths);
552 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200553
554 CLEAR(config->executable);
Steve Dower323e7432019-06-29 14:28:59 -0700555 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200556 CLEAR(config->prefix);
557 CLEAR(config->base_prefix);
558 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200559 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200560
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200561 CLEAR(config->filesystem_encoding);
562 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200563 CLEAR(config->stdio_encoding);
564 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100565 CLEAR(config->run_command);
566 CLEAR(config->run_module);
567 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400568 CLEAR(config->check_hash_pycs_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200569#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200570}
571
572
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700573void
Victor Stinner331a6a52019-05-27 16:39:22 +0200574_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200575{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200576 memset(config, 0, sizeof(*config));
Victor Stinner6e128382019-09-28 04:50:43 +0200577
Victor Stinner022be022019-05-22 23:58:50 +0200578 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200579 config->isolated = -1;
580 config->use_environment = -1;
581 config->dev_mode = -1;
582 config->install_signal_handlers = 1;
583 config->use_hash_seed = -1;
584 config->faulthandler = -1;
585 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200586 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200587 config->parse_argv = 0;
588 config->site_import = -1;
589 config->bytes_warning = -1;
590 config->inspect = -1;
591 config->interactive = -1;
592 config->optimization_level = -1;
593 config->parser_debug= -1;
594 config->write_bytecode = -1;
595 config->verbose = -1;
596 config->quiet = -1;
597 config->user_site_directory = -1;
598 config->configure_c_stdio = 0;
599 config->buffered_stdio = -1;
600 config->_install_importlib = 1;
601 config->check_hash_pycs_mode = NULL;
602 config->pathconfig_warnings = -1;
603 config->_init_main = 1;
604#ifdef MS_WINDOWS
605 config->legacy_windows_stdio = -1;
606#endif
607}
608
609
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700610static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200611config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200612{
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700613 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200614
615 config->isolated = 0;
616 config->use_environment = 1;
617 config->site_import = 1;
618 config->bytes_warning = 0;
619 config->inspect = 0;
620 config->interactive = 0;
621 config->optimization_level = 0;
622 config->parser_debug= 0;
623 config->write_bytecode = 1;
624 config->verbose = 0;
625 config->quiet = 0;
626 config->user_site_directory = 1;
627 config->buffered_stdio = 1;
628 config->pathconfig_warnings = 1;
629#ifdef MS_WINDOWS
630 config->legacy_windows_stdio = 0;
631#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200632}
633
634
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700635void
Victor Stinner331a6a52019-05-27 16:39:22 +0200636PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200637{
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700638 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200639
Victor Stinner022be022019-05-22 23:58:50 +0200640 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200641 config->configure_c_stdio = 1;
642 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200643}
644
645
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700646void
Victor Stinner331a6a52019-05-27 16:39:22 +0200647PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200648{
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700649 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200650
Victor Stinner022be022019-05-22 23:58:50 +0200651 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200652 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200653 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200654 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200655 config->dev_mode = 0;
656 config->install_signal_handlers = 0;
657 config->use_hash_seed = 0;
658 config->faulthandler = 0;
659 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200660 config->pathconfig_warnings = 0;
661#ifdef MS_WINDOWS
662 config->legacy_windows_stdio = 0;
663#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200664}
665
666
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200667/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200668PyStatus
669PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200670{
Victor Stinner331a6a52019-05-27 16:39:22 +0200671 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
672 if (_PyStatus_EXCEPTION(status)) {
673 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200674 }
675
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200676 wchar_t *str2;
677 if (str != NULL) {
678 str2 = _PyMem_RawWcsdup(str);
679 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200680 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200681 }
682 }
683 else {
684 str2 = NULL;
685 }
686 PyMem_RawFree(*config_str);
687 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200688 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200689}
690
691
Victor Stinner331a6a52019-05-27 16:39:22 +0200692static PyStatus
693config_set_bytes_string(PyConfig *config, wchar_t **config_str,
694 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200695{
Victor Stinner331a6a52019-05-27 16:39:22 +0200696 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
697 if (_PyStatus_EXCEPTION(status)) {
698 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400699 }
700
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200701 wchar_t *str2;
702 if (str != NULL) {
703 size_t len;
704 str2 = Py_DecodeLocale(str, &len);
705 if (str2 == NULL) {
706 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200707 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200708 }
709 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200710 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200711 }
712 }
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 +0200723#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
724 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400725
726
Victor Stinner70005ac2019-05-02 15:25:34 -0400727/* Decode str using Py_DecodeLocale() and set the result into *config_str.
728 Pre-initialize Python if needed to ensure that encodings are properly
729 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200730PyStatus
731PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200732 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400733{
Victor Stinner331a6a52019-05-27 16:39:22 +0200734 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400735}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200736
737
Victor Stinner331a6a52019-05-27 16:39:22 +0200738PyStatus
739_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200740{
Victor Stinner331a6a52019-05-27 16:39:22 +0200741 PyStatus status;
Victor Stinner6e128382019-09-28 04:50:43 +0200742
Victor Stinner331a6a52019-05-27 16:39:22 +0200743 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200744
745#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200746#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200747 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200748 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
749 if (_PyStatus_EXCEPTION(status)) { \
750 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200751 } \
752 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100753#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200754 do { \
Miss Islington (bot)96f581c2019-07-01 10:39:58 -0700755 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200756 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200757 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200758 } while (0)
759
Victor Stinner6d1c4672019-05-20 11:02:00 +0200760 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100761 COPY_ATTR(isolated);
762 COPY_ATTR(use_environment);
763 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200764 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200765 COPY_ATTR(use_hash_seed);
766 COPY_ATTR(hash_seed);
767 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200768 COPY_ATTR(faulthandler);
769 COPY_ATTR(tracemalloc);
770 COPY_ATTR(import_time);
771 COPY_ATTR(show_ref_count);
772 COPY_ATTR(show_alloc_count);
773 COPY_ATTR(dump_refs);
774 COPY_ATTR(malloc_stats);
775
Victor Stinner124b9eb2018-08-29 01:29:06 +0200776 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200777 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200778 COPY_WSTR_ATTR(home);
779 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200780
Victor Stinnerae239f62019-05-16 17:02:56 +0200781 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100782 COPY_WSTRLIST(argv);
783 COPY_WSTRLIST(warnoptions);
784 COPY_WSTRLIST(xoptions);
785 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200786 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200787
Victor Stinner124b9eb2018-08-29 01:29:06 +0200788 COPY_WSTR_ATTR(executable);
Steve Dower323e7432019-06-29 14:28:59 -0700789 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200790 COPY_WSTR_ATTR(prefix);
791 COPY_WSTR_ATTR(base_prefix);
792 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200793 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200794
Victor Stinner6c785c02018-08-01 17:56:14 +0200795 COPY_ATTR(site_import);
796 COPY_ATTR(bytes_warning);
797 COPY_ATTR(inspect);
798 COPY_ATTR(interactive);
799 COPY_ATTR(optimization_level);
800 COPY_ATTR(parser_debug);
801 COPY_ATTR(write_bytecode);
802 COPY_ATTR(verbose);
803 COPY_ATTR(quiet);
804 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200805 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200806 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400807 COPY_WSTR_ATTR(filesystem_encoding);
808 COPY_WSTR_ATTR(filesystem_errors);
809 COPY_WSTR_ATTR(stdio_encoding);
810 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200811#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200812 COPY_ATTR(legacy_windows_stdio);
813#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100814 COPY_ATTR(skip_source_first_line);
815 COPY_WSTR_ATTR(run_command);
816 COPY_WSTR_ATTR(run_module);
817 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400818 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200819 COPY_ATTR(pathconfig_warnings);
820 COPY_ATTR(_init_main);
Victor Stinner6c785c02018-08-01 17:56:14 +0200821
822#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200823#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200824#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200825 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200826}
827
828
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100829static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200830config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100831{
832 PyObject *dict;
833
834 dict = PyDict_New();
835 if (dict == NULL) {
836 return NULL;
837 }
838
839#define SET_ITEM(KEY, EXPR) \
840 do { \
841 PyObject *obj = (EXPR); \
842 if (obj == NULL) { \
843 goto fail; \
844 } \
845 int res = PyDict_SetItemString(dict, (KEY), obj); \
846 Py_DECREF(obj); \
847 if (res < 0) { \
848 goto fail; \
849 } \
850 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100851#define SET_ITEM_INT(ATTR) \
852 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
853#define SET_ITEM_UINT(ATTR) \
854 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100855#define FROM_WSTRING(STR) \
856 ((STR != NULL) ? \
857 PyUnicode_FromWideChar(STR, -1) \
858 : (Py_INCREF(Py_None), Py_None))
859#define SET_ITEM_WSTR(ATTR) \
860 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
861#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200862 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100863
Victor Stinner6d1c4672019-05-20 11:02:00 +0200864 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100865 SET_ITEM_INT(isolated);
866 SET_ITEM_INT(use_environment);
867 SET_ITEM_INT(dev_mode);
868 SET_ITEM_INT(install_signal_handlers);
869 SET_ITEM_INT(use_hash_seed);
870 SET_ITEM_UINT(hash_seed);
871 SET_ITEM_INT(faulthandler);
872 SET_ITEM_INT(tracemalloc);
873 SET_ITEM_INT(import_time);
874 SET_ITEM_INT(show_ref_count);
875 SET_ITEM_INT(show_alloc_count);
876 SET_ITEM_INT(dump_refs);
877 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400878 SET_ITEM_WSTR(filesystem_encoding);
879 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100880 SET_ITEM_WSTR(pycache_prefix);
881 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200882 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100883 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100884 SET_ITEM_WSTRLIST(xoptions);
885 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200886 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100887 SET_ITEM_WSTR(home);
888 SET_ITEM_WSTRLIST(module_search_paths);
889 SET_ITEM_WSTR(executable);
Steve Dower323e7432019-06-29 14:28:59 -0700890 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100891 SET_ITEM_WSTR(prefix);
892 SET_ITEM_WSTR(base_prefix);
893 SET_ITEM_WSTR(exec_prefix);
894 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100895 SET_ITEM_INT(site_import);
896 SET_ITEM_INT(bytes_warning);
897 SET_ITEM_INT(inspect);
898 SET_ITEM_INT(interactive);
899 SET_ITEM_INT(optimization_level);
900 SET_ITEM_INT(parser_debug);
901 SET_ITEM_INT(write_bytecode);
902 SET_ITEM_INT(verbose);
903 SET_ITEM_INT(quiet);
904 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200905 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100906 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400907 SET_ITEM_WSTR(stdio_encoding);
908 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100909#ifdef MS_WINDOWS
910 SET_ITEM_INT(legacy_windows_stdio);
911#endif
912 SET_ITEM_INT(skip_source_first_line);
913 SET_ITEM_WSTR(run_command);
914 SET_ITEM_WSTR(run_module);
915 SET_ITEM_WSTR(run_filename);
916 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400917 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200918 SET_ITEM_INT(pathconfig_warnings);
919 SET_ITEM_INT(_init_main);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100920
921 return dict;
922
923fail:
924 Py_DECREF(dict);
925 return NULL;
926
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100927#undef FROM_WSTRING
928#undef SET_ITEM
929#undef SET_ITEM_INT
930#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100931#undef SET_ITEM_WSTR
932#undef SET_ITEM_WSTRLIST
933}
934
935
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100936static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200937config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200938{
Victor Stinner20004952019-03-26 02:31:11 +0100939 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200940}
941
942
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100943/* Get a copy of the environment variable as wchar_t*.
944 Return 0 on success, but *dest can be NULL.
945 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200946static PyStatus
947config_get_env_dup(PyConfig *config,
948 wchar_t **dest,
949 wchar_t *wname, char *name,
950 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200951{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200952 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100953 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200954
Victor Stinner20004952019-03-26 02:31:11 +0100955 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200956 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200957 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200958 }
959
960#ifdef MS_WINDOWS
961 const wchar_t *var = _wgetenv(wname);
962 if (!var || var[0] == '\0') {
963 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200964 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200965 }
966
Victor Stinner331a6a52019-05-27 16:39:22 +0200967 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +0200968#else
969 const char *var = getenv(name);
970 if (!var || var[0] == '\0') {
971 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200972 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200973 }
974
Victor Stinner331a6a52019-05-27 16:39:22 +0200975 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +0200976#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200977}
978
979
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200980#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200981 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200982
983
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100984static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200985config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200986{
Victor Stinner022be022019-05-22 23:58:50 +0200987 if (config->_config_init != _PyConfig_INIT_COMPAT) {
988 /* Python and Isolated configuration ignore global variables */
989 return;
990 }
991
Victor Stinner6c785c02018-08-01 17:56:14 +0200992#define COPY_FLAG(ATTR, VALUE) \
993 if (config->ATTR == -1) { \
994 config->ATTR = VALUE; \
995 }
996#define COPY_NOT_FLAG(ATTR, VALUE) \
997 if (config->ATTR == -1) { \
998 config->ATTR = !(VALUE); \
999 }
1000
Victor Stinner20004952019-03-26 02:31:11 +01001001 COPY_FLAG(isolated, Py_IsolatedFlag);
1002 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001003 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1004 COPY_FLAG(inspect, Py_InspectFlag);
1005 COPY_FLAG(interactive, Py_InteractiveFlag);
1006 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1007 COPY_FLAG(parser_debug, Py_DebugFlag);
1008 COPY_FLAG(verbose, Py_VerboseFlag);
1009 COPY_FLAG(quiet, Py_QuietFlag);
1010#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001011 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1012#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001013 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001014
Victor Stinner6c785c02018-08-01 17:56:14 +02001015 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1016 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1017 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1018 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1019
Victor Stinner6c785c02018-08-01 17:56:14 +02001020#undef COPY_FLAG
1021#undef COPY_NOT_FLAG
1022}
1023
1024
1025/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001026static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001027config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001028{
1029#define COPY_FLAG(ATTR, VAR) \
1030 if (config->ATTR != -1) { \
1031 VAR = config->ATTR; \
1032 }
1033#define COPY_NOT_FLAG(ATTR, VAR) \
1034 if (config->ATTR != -1) { \
1035 VAR = !config->ATTR; \
1036 }
1037
Victor Stinner20004952019-03-26 02:31:11 +01001038 COPY_FLAG(isolated, Py_IsolatedFlag);
1039 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001040 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1041 COPY_FLAG(inspect, Py_InspectFlag);
1042 COPY_FLAG(interactive, Py_InteractiveFlag);
1043 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1044 COPY_FLAG(parser_debug, Py_DebugFlag);
1045 COPY_FLAG(verbose, Py_VerboseFlag);
1046 COPY_FLAG(quiet, Py_QuietFlag);
1047#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001048 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1049#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001050 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001051
Victor Stinner6c785c02018-08-01 17:56:14 +02001052 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1053 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1054 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1055 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1056
Victor Stinner6c785c02018-08-01 17:56:14 +02001057 /* Random or non-zero hash seed */
1058 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1059 config->hash_seed != 0);
1060
1061#undef COPY_FLAG
1062#undef COPY_NOT_FLAG
1063}
1064
1065
1066/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1067 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001068static PyStatus
1069config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001070{
Victor Stinner331a6a52019-05-27 16:39:22 +02001071 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001072
Victor Stinner6c785c02018-08-01 17:56:14 +02001073 /* If Py_SetProgramName() was called, use its value */
1074 const wchar_t *program_name = _Py_path_config.program_name;
1075 if (program_name != NULL) {
1076 config->program_name = _PyMem_RawWcsdup(program_name);
1077 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001078 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001079 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001080 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001081 }
1082
1083#ifdef __APPLE__
1084 /* On MacOS X, when the Python interpreter is embedded in an
1085 application bundle, it gets executed by a bootstrapping script
1086 that does os.execve() with an argv[0] that's different from the
1087 actual Python executable. This is needed to keep the Finder happy,
1088 or rather, to work around Apple's overly strict requirements of
1089 the process name. However, we still need a usable sys.executable,
1090 so the actual executable path is passed in an environment variable.
1091 See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
1092 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001093 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001094 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001095 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1096 "PYTHONEXECUTABLE environment variable");
1097 if (_PyStatus_EXCEPTION(status)) {
1098 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001099 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001100 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001101 }
1102#ifdef WITH_NEXT_FRAMEWORK
1103 else {
1104 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1105 if (pyvenv_launcher && *pyvenv_launcher) {
1106 /* Used by Mac/Tools/pythonw.c to forward
1107 * the argv0 of the stub executable
1108 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001109 status = CONFIG_SET_BYTES_STR(config,
1110 &config->program_name,
1111 pyvenv_launcher,
1112 "__PYVENV_LAUNCHER__ environment variable");
1113 if (_PyStatus_EXCEPTION(status)) {
1114 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001115 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001116 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001117 }
1118 }
1119#endif /* WITH_NEXT_FRAMEWORK */
1120#endif /* __APPLE__ */
1121
Victor Stinnerfed02e12019-05-17 11:12:09 +02001122 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001123 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001124 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1125 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1126 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001127 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001128 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001129 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001130 }
1131
Victor Stinnerfed02e12019-05-17 11:12:09 +02001132 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001133#ifdef MS_WINDOWS
1134 const wchar_t *default_program_name = L"python";
1135#else
1136 const wchar_t *default_program_name = L"python3";
1137#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001138 status = PyConfig_SetString(config, &config->program_name,
1139 default_program_name);
1140 if (_PyStatus_EXCEPTION(status)) {
1141 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001142 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001143 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001144}
1145
Victor Stinner331a6a52019-05-27 16:39:22 +02001146static PyStatus
1147config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001148{
1149 assert(config->executable == NULL);
1150
1151 /* If Py_SetProgramFullPath() was called, use its value */
1152 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1153 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001154 PyStatus status = PyConfig_SetString(config,
1155 &config->executable,
1156 program_full_path);
1157 if (_PyStatus_EXCEPTION(status)) {
1158 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001159 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001160 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001161 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001162 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001163}
Victor Stinner6c785c02018-08-01 17:56:14 +02001164
Victor Stinner4fffd382019-03-06 01:44:31 +01001165
Victor Stinner6c785c02018-08-01 17:56:14 +02001166static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001167config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001168{
Victor Stinner74f65682019-03-15 15:08:05 +01001169 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001170}
1171
1172
Victor Stinner331a6a52019-05-27 16:39:22 +02001173static PyStatus
1174config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001175{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001176 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001177
1178 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001179 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001180 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001181 PyStatus status = PyConfig_SetString(config, &config->home, home);
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 Stinner1a9f0d82019-05-01 15:22:52 +02001188 return CONFIG_GET_ENV_DUP(config, &config->home,
1189 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001190}
1191
1192
Victor Stinner331a6a52019-05-27 16:39:22 +02001193static PyStatus
1194config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001195{
Victor Stinner331a6a52019-05-27 16:39:22 +02001196 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001197
1198 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1199 /* Convert a text seed to a numeric one */
1200 if (seed_text && strcmp(seed_text, "random") != 0) {
1201 const char *endptr = seed_text;
1202 unsigned long seed;
1203 errno = 0;
1204 seed = strtoul(seed_text, (char **)&endptr, 10);
1205 if (*endptr != '\0'
1206 || seed > 4294967295UL
1207 || (errno == ERANGE && seed == ULONG_MAX))
1208 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001209 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001210 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001211 }
1212 /* Use a specific hash */
1213 config->use_hash_seed = 1;
1214 config->hash_seed = seed;
1215 }
1216 else {
1217 /* Use a random hash */
1218 config->use_hash_seed = 0;
1219 config->hash_seed = 0;
1220 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001221 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001222}
1223
1224
Victor Stinner6c785c02018-08-01 17:56:14 +02001225static int
1226config_wstr_to_int(const wchar_t *wstr, int *result)
1227{
1228 const wchar_t *endptr = wstr;
1229 errno = 0;
1230 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1231 if (*endptr != '\0' || errno == ERANGE) {
1232 return -1;
1233 }
1234 if (value < INT_MIN || value > INT_MAX) {
1235 return -1;
1236 }
1237
1238 *result = (int)value;
1239 return 0;
1240}
1241
1242
Victor Stinner331a6a52019-05-27 16:39:22 +02001243static PyStatus
1244config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001245{
Victor Stinner331a6a52019-05-27 16:39:22 +02001246 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001247 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001248
Victor Stinner6c785c02018-08-01 17:56:14 +02001249 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001250 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1251 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1252 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1253 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001254
1255 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001256 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001257 if (dont_write_bytecode) {
1258 config->write_bytecode = 0;
1259 }
1260
1261 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001262 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001263 if (no_user_site_directory) {
1264 config->user_site_directory = 0;
1265 }
1266
1267 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001268 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001269 if (unbuffered_stdio) {
1270 config->buffered_stdio = 0;
1271 }
1272
1273#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001274 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001275 "PYTHONLEGACYWINDOWSSTDIO");
1276#endif
1277
Victor Stinner331a6a52019-05-27 16:39:22 +02001278 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001279 config->dump_refs = 1;
1280 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001281 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001282 config->malloc_stats = 1;
1283 }
1284
Victor Stinner331a6a52019-05-27 16:39:22 +02001285 if (config->pythonpath_env == NULL) {
1286 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1287 L"PYTHONPATH", "PYTHONPATH");
1288 if (_PyStatus_EXCEPTION(status)) {
1289 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001290 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001291 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001292
1293 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001294 status = config_init_hash_seed(config);
1295 if (_PyStatus_EXCEPTION(status)) {
1296 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001297 }
1298 }
1299
Victor Stinner331a6a52019-05-27 16:39:22 +02001300 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001301}
1302
1303
Victor Stinner331a6a52019-05-27 16:39:22 +02001304static PyStatus
1305config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001306{
1307 int nframe;
1308 int valid;
1309
Victor Stinner331a6a52019-05-27 16:39:22 +02001310 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001311 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001312 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001313 valid = (nframe >= 0);
1314 }
1315 else {
1316 valid = 0;
1317 }
1318 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001319 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001320 }
1321 config->tracemalloc = nframe;
1322 }
1323
1324 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1325 if (xoption) {
1326 const wchar_t *sep = wcschr(xoption, L'=');
1327 if (sep) {
1328 if (!config_wstr_to_int(sep + 1, &nframe)) {
1329 valid = (nframe >= 0);
1330 }
1331 else {
1332 valid = 0;
1333 }
1334 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001335 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1336 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001337 }
1338 }
1339 else {
1340 /* -X tracemalloc behaves as -X tracemalloc=1 */
1341 nframe = 1;
1342 }
1343 config->tracemalloc = nframe;
1344 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001345 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001346}
1347
1348
Victor Stinner331a6a52019-05-27 16:39:22 +02001349static PyStatus
1350config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001351{
1352 assert(config->pycache_prefix == NULL);
1353
1354 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1355 if (xoption) {
1356 const wchar_t *sep = wcschr(xoption, L'=');
1357 if (sep && wcslen(sep) > 1) {
1358 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1359 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001360 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001361 }
1362 }
1363 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001364 // PYTHONPYCACHEPREFIX env var ignored
1365 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001366 config->pycache_prefix = NULL;
1367 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001368 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001369 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001370
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001371 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1372 L"PYTHONPYCACHEPREFIX",
1373 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001374}
1375
1376
Victor Stinner331a6a52019-05-27 16:39:22 +02001377static PyStatus
1378config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001379{
1380 /* More complex options configured by env var and -X option */
1381 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001382 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001383 || config_get_xoption(config, L"faulthandler")) {
1384 config->faulthandler = 1;
1385 }
1386 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001387 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001388 || config_get_xoption(config, L"importtime")) {
1389 config->import_time = 1;
1390 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001391
Victor Stinner331a6a52019-05-27 16:39:22 +02001392 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001393 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001394 status = config_init_tracemalloc(config);
1395 if (_PyStatus_EXCEPTION(status)) {
1396 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001397 }
1398 }
1399
1400 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001401 status = config_init_pycache_prefix(config);
1402 if (_PyStatus_EXCEPTION(status)) {
1403 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001404 }
1405 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001406 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001407}
1408
1409
Victor Stinner709d23d2019-05-02 14:56:30 -04001410static const wchar_t *
Victor Stinner331a6a52019-05-27 16:39:22 +02001411config_get_stdio_errors(const PyConfig *config)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001412{
1413#ifndef MS_WINDOWS
1414 const char *loc = setlocale(LC_CTYPE, NULL);
1415 if (loc != NULL) {
1416 /* surrogateescape is the default in the legacy C and POSIX locales */
1417 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001418 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001419 }
1420
1421#ifdef PY_COERCE_C_LOCALE
1422 /* surrogateescape is the default in locale coercion target locales */
1423 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001424 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001425 }
1426#endif
1427 }
1428
Victor Stinner709d23d2019-05-02 14:56:30 -04001429 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001430#else
1431 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001432 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001433#endif
1434}
1435
1436
Victor Stinner331a6a52019-05-27 16:39:22 +02001437static PyStatus
1438config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001439{
1440#ifdef MS_WINDOWS
1441 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001442 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001443 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001444#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001445 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001446#else
1447 const char *encoding = nl_langinfo(CODESET);
1448 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001449 return _PyStatus_ERR("failed to get the locale encoding: "
1450 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001451 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001452 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001453 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001454 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001455 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001456#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001457}
1458
1459
Victor Stinner331a6a52019-05-27 16:39:22 +02001460static PyStatus
1461config_init_stdio_encoding(PyConfig *config,
1462 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001463{
Victor Stinner331a6a52019-05-27 16:39:22 +02001464 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001465
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001466 /* If Py_SetStandardStreamEncoding() have been called, use these
1467 parameters. */
1468 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001469 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1470 _Py_StandardStreamEncoding,
1471 "_Py_StandardStreamEncoding");
1472 if (_PyStatus_EXCEPTION(status)) {
1473 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001474 }
1475 }
1476
1477 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001478 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1479 _Py_StandardStreamErrors,
1480 "_Py_StandardStreamErrors");
1481 if (_PyStatus_EXCEPTION(status)) {
1482 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001483 }
1484 }
1485
1486 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001487 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001488 }
1489
1490 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001491 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001492 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001493 char *pythonioencoding = _PyMem_RawStrdup(opt);
1494 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001495 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001496 }
1497
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001498 char *errors = strchr(pythonioencoding, ':');
1499 if (errors) {
1500 *errors = '\0';
1501 errors++;
1502 if (!errors[0]) {
1503 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001504 }
1505 }
1506
1507 /* Does PYTHONIOENCODING contain an encoding? */
1508 if (pythonioencoding[0]) {
1509 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001510 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1511 pythonioencoding,
1512 "PYTHONIOENCODING environment variable");
1513 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001514 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001515 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001516 }
1517 }
1518
1519 /* If the encoding is set but not the error handler,
1520 use "strict" error handler by default.
1521 PYTHONIOENCODING=latin1 behaves as
1522 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001523 if (!errors) {
1524 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001525 }
1526 }
1527
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001528 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001529 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1530 errors,
1531 "PYTHONIOENCODING environment variable");
1532 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001533 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001534 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001535 }
1536 }
1537
1538 PyMem_RawFree(pythonioencoding);
1539 }
1540
1541 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001542 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001543 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001544 status = PyConfig_SetString(config, &config->stdio_encoding,
1545 L"utf-8");
1546 if (_PyStatus_EXCEPTION(status)) {
1547 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001548 }
1549 }
1550 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001551 status = PyConfig_SetString(config, &config->stdio_errors,
1552 L"surrogateescape");
1553 if (_PyStatus_EXCEPTION(status)) {
1554 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001555 }
1556 }
1557 }
1558
1559 /* Choose the default error handler based on the current locale. */
1560 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001561 status = config_get_locale_encoding(config, &config->stdio_encoding);
1562 if (_PyStatus_EXCEPTION(status)) {
1563 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001564 }
1565 }
1566 if (config->stdio_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001567 const wchar_t *errors = config_get_stdio_errors(config);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001568 assert(errors != NULL);
1569
Victor Stinner331a6a52019-05-27 16:39:22 +02001570 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1571 if (_PyStatus_EXCEPTION(status)) {
1572 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001573 }
1574 }
1575
Victor Stinner331a6a52019-05-27 16:39:22 +02001576 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001577}
1578
1579
Victor Stinner331a6a52019-05-27 16:39:22 +02001580static PyStatus
1581config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001582{
Victor Stinner331a6a52019-05-27 16:39:22 +02001583 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001584
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001585 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001586#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001587 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001588#else
Victor Stinnere2510952019-05-02 11:28:57 -04001589
1590#ifdef MS_WINDOWS
1591 if (preconfig->legacy_windows_fs_encoding) {
1592 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001593 status = PyConfig_SetString(config, &config->filesystem_encoding,
1594 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001595 }
1596 else
1597#endif
Victor Stinner20004952019-03-26 02:31:11 +01001598 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001599 status = PyConfig_SetString(config, &config->filesystem_encoding,
1600 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001601 }
Victor Stinnere2510952019-05-02 11:28:57 -04001602#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001603 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001604 status = PyConfig_SetString(config, &config->filesystem_encoding,
1605 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001606 }
Victor Stinnere2510952019-05-02 11:28:57 -04001607#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001608 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001609#ifdef MS_WINDOWS
1610 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001611 status = PyConfig_SetString(config, &config->filesystem_encoding,
1612 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001613#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001614 status = config_get_locale_encoding(config,
1615 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001616#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001617 }
Victor Stinnere2510952019-05-02 11:28:57 -04001618#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001619
Victor Stinner331a6a52019-05-27 16:39:22 +02001620 if (_PyStatus_EXCEPTION(status)) {
1621 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001622 }
1623 }
1624
1625 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001626 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001627#ifdef MS_WINDOWS
1628 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001629 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001630 }
1631 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001632 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001633 }
1634#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001635 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001636#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001637 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1638 if (_PyStatus_EXCEPTION(status)) {
1639 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001640 }
1641 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001642 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001643}
1644
1645
Victor Stinner331a6a52019-05-27 16:39:22 +02001646static PyStatus
1647config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001648{
Victor Stinner331a6a52019-05-27 16:39:22 +02001649 PyStatus status;
1650 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001651
Victor Stinner20004952019-03-26 02:31:11 +01001652 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001653 status = config_read_env_vars(config);
1654 if (_PyStatus_EXCEPTION(status)) {
1655 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001656 }
1657 }
1658
1659 /* -X options */
1660 if (config_get_xoption(config, L"showrefcount")) {
1661 config->show_ref_count = 1;
1662 }
1663 if (config_get_xoption(config, L"showalloccount")) {
1664 config->show_alloc_count = 1;
1665 }
1666
Victor Stinner331a6a52019-05-27 16:39:22 +02001667 status = config_read_complex_options(config);
1668 if (_PyStatus_EXCEPTION(status)) {
1669 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001670 }
1671
Victor Stinner6c785c02018-08-01 17:56:14 +02001672 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001673 status = config_init_home(config);
1674 if (_PyStatus_EXCEPTION(status)) {
1675 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001676 }
1677 }
1678
Steve Dower177a41a2018-11-17 20:41:48 -08001679 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001680 status = config_init_executable(config);
1681 if (_PyStatus_EXCEPTION(status)) {
1682 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001683 }
1684 }
1685
Victor Stinner6c785c02018-08-01 17:56:14 +02001686 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001687 status = _PyConfig_InitPathConfig(config);
1688 if (_PyStatus_EXCEPTION(status)) {
1689 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001690 }
1691 }
1692
1693 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001694 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001695 if (config->faulthandler < 0) {
1696 config->faulthandler = 1;
1697 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001698 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001699 if (config->faulthandler < 0) {
1700 config->faulthandler = 0;
1701 }
1702 if (config->tracemalloc < 0) {
1703 config->tracemalloc = 0;
1704 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001705 if (config->use_hash_seed < 0) {
1706 config->use_hash_seed = 0;
1707 config->hash_seed = 0;
1708 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001709
Victor Stinner70fead22018-08-29 13:45:34 +02001710 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001711 status = config_init_fs_encoding(config, preconfig);
1712 if (_PyStatus_EXCEPTION(status)) {
1713 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001714 }
1715 }
1716
Victor Stinner331a6a52019-05-27 16:39:22 +02001717 status = config_init_stdio_encoding(config, preconfig);
1718 if (_PyStatus_EXCEPTION(status)) {
1719 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001720 }
1721
Victor Stinner62599762019-03-15 16:03:23 +01001722 if (config->argv.length < 1) {
1723 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001724 status = PyWideStringList_Append(&config->argv, L"");
1725 if (_PyStatus_EXCEPTION(status)) {
1726 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001727 }
1728 }
Victor Stinner870b0352019-05-17 03:15:12 +02001729
1730 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001731 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1732 L"default");
1733 if (_PyStatus_EXCEPTION(status)) {
1734 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001735 }
1736 }
1737
1738 if (config->configure_c_stdio < 0) {
1739 config->configure_c_stdio = 1;
1740 }
1741
Victor Stinner331a6a52019-05-27 16:39:22 +02001742 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001743}
Victor Stinner5ed69952018-11-06 15:59:52 +01001744
1745
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001746static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001747config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001748{
1749#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1750 /* don't translate newlines (\r\n <=> \n) */
1751 _setmode(fileno(stdin), O_BINARY);
1752 _setmode(fileno(stdout), O_BINARY);
1753 _setmode(fileno(stderr), O_BINARY);
1754#endif
1755
1756 if (!config->buffered_stdio) {
1757#ifdef HAVE_SETVBUF
1758 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1759 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1760 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1761#else /* !HAVE_SETVBUF */
1762 setbuf(stdin, (char *)NULL);
1763 setbuf(stdout, (char *)NULL);
1764 setbuf(stderr, (char *)NULL);
1765#endif /* !HAVE_SETVBUF */
1766 }
1767 else if (config->interactive) {
1768#ifdef MS_WINDOWS
1769 /* Doesn't have to have line-buffered -- use unbuffered */
1770 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1771 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1772#else /* !MS_WINDOWS */
1773#ifdef HAVE_SETVBUF
1774 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1775 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1776#endif /* HAVE_SETVBUF */
1777#endif /* !MS_WINDOWS */
1778 /* Leave stderr alone - it should be unbuffered anyway. */
1779 }
1780}
1781
1782
1783/* Write the configuration:
1784
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001785 - set Py_xxx global configuration variables
1786 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001787void
Victor Stinner331a6a52019-05-27 16:39:22 +02001788_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001789{
Victor Stinner331a6a52019-05-27 16:39:22 +02001790 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001791
1792 if (config->configure_c_stdio) {
1793 config_init_stdio(config);
1794 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001795
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001796 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001797 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001798 preconfig->isolated = config->isolated;
1799 preconfig->use_environment = config->use_environment;
1800 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001801}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001802
1803
Victor Stinner331a6a52019-05-27 16:39:22 +02001804/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001805
1806static void
Victor Stinner2f549082019-03-29 15:13:46 +01001807config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001808{
Victor Stinner2f549082019-03-29 15:13:46 +01001809 FILE *f = error ? stderr : stdout;
1810
1811 fprintf(f, usage_line, program);
1812 if (error)
1813 fprintf(f, "Try `python -h' for more information.\n");
1814 else {
1815 fputs(usage_1, f);
1816 fputs(usage_2, f);
1817 fputs(usage_3, f);
1818 fprintf(f, usage_4, (wint_t)DELIM);
1819 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1820 fputs(usage_6, f);
1821 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001822}
1823
1824
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001825/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001826static PyStatus
1827config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001828 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001829{
Victor Stinner331a6a52019-05-27 16:39:22 +02001830 PyStatus status;
1831 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001832 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001833 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001834
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001835 _PyOS_ResetGetOpt();
1836 do {
1837 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001838 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001839 if (c == EOF) {
1840 break;
1841 }
1842
1843 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001844 if (config->run_command == NULL) {
1845 /* -c is the last option; following arguments
1846 that look like options are left for the
1847 command to interpret. */
1848 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1849 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1850 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001851 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001852 }
1853 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1854 command[len - 2] = '\n';
1855 command[len - 1] = 0;
1856 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001857 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001858 break;
1859 }
1860
1861 if (c == 'm') {
1862 /* -m is the last option; following arguments
1863 that look like options are left for the
1864 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001865 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001866 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1867 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001868 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001869 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001870 }
1871 break;
1872 }
1873
1874 switch (c) {
1875 case 0:
1876 // Handle long option.
1877 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001878 if (wcscmp(_PyOS_optarg, L"always") == 0
1879 || wcscmp(_PyOS_optarg, L"never") == 0
1880 || wcscmp(_PyOS_optarg, L"default") == 0)
1881 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001882 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1883 _PyOS_optarg);
1884 if (_PyStatus_EXCEPTION(status)) {
1885 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001886 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001887 } else {
1888 fprintf(stderr, "--check-hash-based-pycs must be one of "
1889 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001890 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001891 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001892 }
1893 break;
1894
1895 case 'b':
1896 config->bytes_warning++;
1897 break;
1898
1899 case 'd':
1900 config->parser_debug++;
1901 break;
1902
1903 case 'i':
1904 config->inspect++;
1905 config->interactive++;
1906 break;
1907
Victor Stinner6dcb5422019-03-05 02:44:12 +01001908 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001909 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001910 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001911 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001912 break;
1913
1914 /* case 'J': reserved for Jython */
1915
1916 case 'O':
1917 config->optimization_level++;
1918 break;
1919
1920 case 'B':
1921 config->write_bytecode = 0;
1922 break;
1923
1924 case 's':
1925 config->user_site_directory = 0;
1926 break;
1927
1928 case 'S':
1929 config->site_import = 0;
1930 break;
1931
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001932 case 't':
1933 /* ignored for backwards compatibility */
1934 break;
1935
1936 case 'u':
1937 config->buffered_stdio = 0;
1938 break;
1939
1940 case 'v':
1941 config->verbose++;
1942 break;
1943
1944 case 'x':
1945 config->skip_source_first_line = 1;
1946 break;
1947
1948 case 'h':
1949 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001950 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001951 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001952
1953 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01001954 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001955 break;
1956
1957 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02001958 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
1959 if (_PyStatus_EXCEPTION(status)) {
1960 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001961 }
1962 break;
1963
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001964 case 'q':
1965 config->quiet++;
1966 break;
1967
1968 case 'R':
1969 config->use_hash_seed = 0;
1970 break;
1971
1972 /* This space reserved for other options */
1973
1974 default:
1975 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02001976 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001977 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001978 }
1979 } while (1);
1980
Victor Stinner2f549082019-03-29 15:13:46 +01001981 if (print_version) {
1982 printf("Python %s\n",
1983 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02001984 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01001985 }
1986
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001987 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01001988 && _PyOS_optind < argv->length
1989 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01001990 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001991 {
Victor Stinnerfa153762019-03-20 04:25:38 +01001992 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001993 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001994 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001995 }
1996 }
1997
1998 if (config->run_command != NULL || config->run_module != NULL) {
1999 /* Backup _PyOS_optind */
2000 _PyOS_optind--;
2001 }
2002
Victor Stinnerae239f62019-05-16 17:02:56 +02002003 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002004
Victor Stinner331a6a52019-05-27 16:39:22 +02002005 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002006}
2007
2008
2009#ifdef MS_WINDOWS
2010# define WCSTOK wcstok_s
2011#else
2012# define WCSTOK wcstok
2013#endif
2014
2015/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002016static PyStatus
2017config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002018{
Victor Stinner331a6a52019-05-27 16:39:22 +02002019 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002020 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2021 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002022 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002023 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002024 if (_PyStatus_EXCEPTION(status)) {
2025 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002026 }
2027
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002028 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002029 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002030 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002031 }
2032
2033
2034 wchar_t *warning, *context = NULL;
2035 for (warning = WCSTOK(env, L",", &context);
2036 warning != NULL;
2037 warning = WCSTOK(NULL, L",", &context))
2038 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002039 status = PyWideStringList_Append(warnoptions, warning);
2040 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002041 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002042 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002043 }
2044 }
2045 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002046 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002047}
2048
2049
Victor Stinner331a6a52019-05-27 16:39:22 +02002050static PyStatus
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002051warnoptions_append(PyConfig *config, PyWideStringList *options,
2052 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002053{
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002054 /* config_init_warnoptions() add existing config warnoptions at the end:
2055 ensure that the new option is not already present in this list to
2056 prevent change the options order whne config_init_warnoptions() is
2057 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002058 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002059 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002060 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002061 }
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002062 if (_PyWideStringList_Find(options, option)) {
2063 /* Already present: do nothing */
2064 return _PyStatus_OK();
2065 }
2066 return PyWideStringList_Append(options, option);
2067}
2068
2069
2070static PyStatus
2071warnoptions_extend(PyConfig *config, PyWideStringList *options,
2072 const PyWideStringList *options2)
2073{
2074 const Py_ssize_t len = options2->length;
2075 wchar_t *const *items = options2->items;
2076
2077 for (Py_ssize_t i = 0; i < len; i++) {
2078 PyStatus status = warnoptions_append(config, options, items[i]);
2079 if (_PyStatus_EXCEPTION(status)) {
2080 return status;
2081 }
2082 }
2083 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002084}
2085
2086
Victor Stinner331a6a52019-05-27 16:39:22 +02002087static PyStatus
2088config_init_warnoptions(PyConfig *config,
2089 const PyWideStringList *cmdline_warnoptions,
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002090 const PyWideStringList *env_warnoptions,
2091 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002092{
Victor Stinner331a6a52019-05-27 16:39:22 +02002093 PyStatus status;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002094 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002095
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002096 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002097 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002098 * - any implicit filters added by _warnings.c/warnings.py
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002099 * - PyConfig.dev_mode: "default" filter
2100 * - PYTHONWARNINGS environment variable
2101 * - '-W' command line options
2102 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2103 * "default::BytesWarning" or "error::BytesWarning" filter
2104 * - early PySys_AddWarnOption() calls
2105 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002106 *
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002107 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2108 * module works on the basis of "the most recently added filter will be
2109 * checked first", we add the lowest precedence entries first so that later
2110 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002111 */
2112
Victor Stinner20004952019-03-26 02:31:11 +01002113 if (config->dev_mode) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002114 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002115 if (_PyStatus_EXCEPTION(status)) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002116 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002117 }
2118 }
2119
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002120 status = warnoptions_extend(config, &options, env_warnoptions);
2121 if (_PyStatus_EXCEPTION(status)) {
2122 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002123 }
2124
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002125 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2126 if (_PyStatus_EXCEPTION(status)) {
2127 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002128 }
2129
2130 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2131 * don't even try to emit a warning, so we skip setting the filter in that
2132 * case.
2133 */
2134 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002135 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002136 if (config->bytes_warning> 1) {
2137 filter = L"error::BytesWarning";
2138 }
2139 else {
2140 filter = L"default::BytesWarning";
2141 }
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002142 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002143 if (_PyStatus_EXCEPTION(status)) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002144 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002145 }
2146 }
Victor Stinneraf84a882019-08-23 21:16:51 +02002147
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002148 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinneraf84a882019-08-23 21:16:51 +02002149 if (_PyStatus_EXCEPTION(status)) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002150 goto error;
Victor Stinneraf84a882019-08-23 21:16:51 +02002151 }
2152
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002153 /* Always add all PyConfig.warnoptions options */
2154 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2155 if (_PyStatus_EXCEPTION(status)) {
2156 goto error;
2157 }
2158
2159 _PyWideStringList_Clear(&config->warnoptions);
2160 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002161 return _PyStatus_OK();
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002162
2163error:
2164 _PyWideStringList_Clear(&options);
2165 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002166}
2167
2168
Victor Stinner331a6a52019-05-27 16:39:22 +02002169static PyStatus
2170config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002171{
Victor Stinner331a6a52019-05-27 16:39:22 +02002172 const PyWideStringList *cmdline_argv = &config->argv;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002173 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002174
Victor Stinner74f65682019-03-15 15:08:05 +01002175 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002176 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002177 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002178 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2179 if (_PyStatus_EXCEPTION(status)) {
2180 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002181 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002182 }
2183 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002184 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002185 slice.length = cmdline_argv->length - opt_index;
2186 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002187 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2188 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002189 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002190 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002191 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002192
2193 wchar_t *arg0 = NULL;
2194 if (config->run_command != NULL) {
2195 /* Force sys.argv[0] = '-c' */
2196 arg0 = L"-c";
2197 }
2198 else if (config->run_module != NULL) {
2199 /* Force sys.argv[0] = '-m'*/
2200 arg0 = L"-m";
2201 }
2202 if (arg0 != NULL) {
2203 arg0 = _PyMem_RawWcsdup(arg0);
2204 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002205 _PyWideStringList_Clear(&config_argv);
2206 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002207 }
2208
Victor Stinnerfa153762019-03-20 04:25:38 +01002209 PyMem_RawFree(config_argv.items[0]);
2210 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002211 }
2212
Victor Stinner331a6a52019-05-27 16:39:22 +02002213 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002214 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002215 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002216}
2217
2218
Victor Stinner331a6a52019-05-27 16:39:22 +02002219static PyStatus
2220core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002221{
Victor Stinner331a6a52019-05-27 16:39:22 +02002222 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002223
Victor Stinnercab5d072019-05-17 19:01:14 +02002224 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002225 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2226 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002227 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002228 }
2229
Victor Stinner331a6a52019-05-27 16:39:22 +02002230 PyPreConfig preconfig;
Victor Stinner6e128382019-09-28 04:50:43 +02002231
2232 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2233 if (_PyStatus_EXCEPTION(status)) {
2234 return status;
2235 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002236
Victor Stinner331a6a52019-05-27 16:39:22 +02002237 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002238
Victor Stinner331a6a52019-05-27 16:39:22 +02002239 status = _PyPreCmdline_Read(precmdline, &preconfig);
2240 if (_PyStatus_EXCEPTION(status)) {
2241 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002242 }
2243
Victor Stinner331a6a52019-05-27 16:39:22 +02002244 status = _PyPreCmdline_SetConfig(precmdline, config);
2245 if (_PyStatus_EXCEPTION(status)) {
2246 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002247 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002248 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002249}
2250
2251
Victor Stinner331a6a52019-05-27 16:39:22 +02002252static PyStatus
2253config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002254{
Victor Stinner331a6a52019-05-27 16:39:22 +02002255 PyStatus status;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002256 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2257 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2258 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002259
Victor Stinnerae239f62019-05-16 17:02:56 +02002260 if (config->parse_argv < 0) {
2261 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002262 }
Victor Stinner870b0352019-05-17 03:15:12 +02002263
Victor Stinnerfed02e12019-05-17 11:12:09 +02002264 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002265 status = config_init_program_name(config);
2266 if (_PyStatus_EXCEPTION(status)) {
2267 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002268 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002269 }
Victor Stinner2f549082019-03-29 15:13:46 +01002270
Victor Stinnerae239f62019-05-16 17:02:56 +02002271 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002272 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002273 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2274 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002275 goto done;
2276 }
2277
Victor Stinner331a6a52019-05-27 16:39:22 +02002278 status = config_update_argv(config, opt_index);
2279 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002280 goto done;
2281 }
Victor Stinner2f549082019-03-29 15:13:46 +01002282 }
2283
Victor Stinner2f549082019-03-29 15:13:46 +01002284 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002285 status = config_init_env_warnoptions(config, &env_warnoptions);
2286 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002287 goto done;
2288 }
2289 }
2290
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002291 /* Handle early PySys_AddWarnOption() calls */
2292 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2293 if (_PyStatus_EXCEPTION(status)) {
2294 goto done;
2295 }
2296
Victor Stinner331a6a52019-05-27 16:39:22 +02002297 status = config_init_warnoptions(config,
Victor Stinneraf84a882019-08-23 21:16:51 +02002298 &cmdline_warnoptions,
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002299 &env_warnoptions,
2300 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002301 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002302 goto done;
2303 }
2304
Victor Stinner331a6a52019-05-27 16:39:22 +02002305 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002306
2307done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002308 _PyWideStringList_Clear(&cmdline_warnoptions);
2309 _PyWideStringList_Clear(&env_warnoptions);
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002310 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002311 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002312}
2313
2314
Victor Stinner331a6a52019-05-27 16:39:22 +02002315PyStatus
2316_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002317{
Victor Stinner331a6a52019-05-27 16:39:22 +02002318 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2319 if (_PyStatus_EXCEPTION(status)) {
2320 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002321 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002322
Victor Stinner5f38b842019-05-01 02:30:12 +02002323 return _PyArgv_AsWstrList(args, &config->argv);
2324}
2325
2326
Victor Stinner70005ac2019-05-02 15:25:34 -04002327/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2328 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002329PyStatus
2330PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002331{
2332 _PyArgv args = {
2333 .argc = argc,
2334 .use_bytes_argv = 1,
2335 .bytes_argv = argv,
2336 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002337 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002338}
2339
2340
Victor Stinner331a6a52019-05-27 16:39:22 +02002341PyStatus
2342PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002343{
2344 _PyArgv args = {
2345 .argc = argc,
2346 .use_bytes_argv = 0,
2347 .bytes_argv = NULL,
2348 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002349 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002350}
2351
2352
Miss Islington (bot)96f581c2019-07-01 10:39:58 -07002353PyStatus
2354PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2355 Py_ssize_t length, wchar_t **items)
2356{
2357 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2358 if (_PyStatus_EXCEPTION(status)) {
2359 return status;
2360 }
2361
2362 PyWideStringList list2 = {.length = length, .items = items};
2363 if (_PyWideStringList_Copy(list, &list2) < 0) {
2364 return _PyStatus_NO_MEMORY();
2365 }
2366 return _PyStatus_OK();
2367}
2368
2369
Victor Stinner331a6a52019-05-27 16:39:22 +02002370/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002371
2372 * Command line arguments
2373 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002374 * Py_xxx global configuration variables
2375
2376 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002377PyStatus
2378PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002379{
Victor Stinner331a6a52019-05-27 16:39:22 +02002380 PyStatus status;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002381 PyWideStringList orig_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002382
Victor Stinner331a6a52019-05-27 16:39:22 +02002383 status = _Py_PreInitializeFromConfig(config, NULL);
2384 if (_PyStatus_EXCEPTION(status)) {
2385 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002386 }
2387
Victor Stinner331a6a52019-05-27 16:39:22 +02002388 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002389
Victor Stinner331a6a52019-05-27 16:39:22 +02002390 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2391 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002392 }
2393
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002394 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002395 status = core_read_precmdline(config, &precmdline);
2396 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002397 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002398 }
2399
Victor Stinner870b0352019-05-17 03:15:12 +02002400 assert(config->isolated >= 0);
2401 if (config->isolated) {
2402 config->use_environment = 0;
2403 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002404 }
2405
Victor Stinner331a6a52019-05-27 16:39:22 +02002406 status = config_read_cmdline(config);
2407 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002408 goto done;
2409 }
2410
Victor Stinneraf84a882019-08-23 21:16:51 +02002411 /* Handle early PySys_AddXOption() calls */
2412 status = _PySys_ReadPreinitXOptions(config);
2413 if (_PyStatus_EXCEPTION(status)) {
2414 goto done;
2415 }
2416
Victor Stinner331a6a52019-05-27 16:39:22 +02002417 status = config_read(config);
2418 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002419 goto done;
2420 }
2421
Victor Stinnercab5d072019-05-17 19:01:14 +02002422 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002423 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002424 goto done;
2425 }
2426
2427 /* Check config consistency */
2428 assert(config->isolated >= 0);
2429 assert(config->use_environment >= 0);
2430 assert(config->dev_mode >= 0);
2431 assert(config->install_signal_handlers >= 0);
2432 assert(config->use_hash_seed >= 0);
2433 assert(config->faulthandler >= 0);
2434 assert(config->tracemalloc >= 0);
2435 assert(config->site_import >= 0);
2436 assert(config->bytes_warning >= 0);
2437 assert(config->inspect >= 0);
2438 assert(config->interactive >= 0);
2439 assert(config->optimization_level >= 0);
2440 assert(config->parser_debug >= 0);
2441 assert(config->write_bytecode >= 0);
2442 assert(config->verbose >= 0);
2443 assert(config->quiet >= 0);
2444 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002445 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002446 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002447 assert(config->buffered_stdio >= 0);
2448 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002449 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002450 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2451 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002452 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2453 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2454 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002455 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002456 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002457 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002458 assert(config->executable != NULL);
Steve Dower323e7432019-06-29 14:28:59 -07002459 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002460 assert(config->prefix != NULL);
2461 assert(config->base_prefix != NULL);
2462 assert(config->exec_prefix != NULL);
2463 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002464 }
2465 assert(config->filesystem_encoding != NULL);
2466 assert(config->filesystem_errors != NULL);
2467 assert(config->stdio_encoding != NULL);
2468 assert(config->stdio_errors != NULL);
2469#ifdef MS_WINDOWS
2470 assert(config->legacy_windows_stdio >= 0);
2471#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002472 /* -c and -m options are exclusive */
2473 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002474 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002475 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002476 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002477
Victor Stinner331a6a52019-05-27 16:39:22 +02002478 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002479
2480done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002481 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002482 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002483 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002484}
Victor Stinner1075d162019-03-25 23:19:57 +01002485
2486
2487PyObject*
2488_Py_GetConfigsAsDict(void)
2489{
Victor Stinner331a6a52019-05-27 16:39:22 +02002490 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002491 PyObject *dict = NULL;
2492
Victor Stinner331a6a52019-05-27 16:39:22 +02002493 result = PyDict_New();
2494 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002495 goto error;
2496 }
2497
Victor Stinner331a6a52019-05-27 16:39:22 +02002498 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002499 dict = _Py_GetGlobalVariablesAsDict();
2500 if (dict == NULL) {
2501 goto error;
2502 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002503 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002504 goto error;
2505 }
2506 Py_CLEAR(dict);
2507
2508 /* pre config */
2509 PyInterpreterState *interp = _PyInterpreterState_Get();
Victor Stinner331a6a52019-05-27 16:39:22 +02002510 const PyPreConfig *pre_config = &_PyRuntime.preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002511 dict = _PyPreConfig_AsDict(pre_config);
2512 if (dict == NULL) {
2513 goto error;
2514 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002515 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002516 goto error;
2517 }
2518 Py_CLEAR(dict);
2519
2520 /* core config */
Victor Stinner331a6a52019-05-27 16:39:22 +02002521 const PyConfig *config = &interp->config;
2522 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002523 if (dict == NULL) {
2524 goto error;
2525 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002526 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002527 goto error;
2528 }
2529 Py_CLEAR(dict);
2530
Victor Stinner331a6a52019-05-27 16:39:22 +02002531 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002532
2533error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002534 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002535 Py_XDECREF(dict);
2536 return NULL;
2537}
Victor Stinnerc5c64252019-09-23 15:59:00 +02002538
2539
2540static void
2541init_dump_ascii_wstr(const wchar_t *str)
2542{
2543 if (str == NULL) {
2544 PySys_WriteStderr("(not set)");
2545 return;
2546 }
2547
2548 PySys_WriteStderr("'");
2549 for (; *str != L'\0'; str++) {
2550 wchar_t ch = *str;
2551 if (ch == L'\'') {
2552 PySys_WriteStderr("\\'");
2553 } else if (0x20 <= ch && ch < 0x7f) {
2554 PySys_WriteStderr("%lc", ch);
2555 }
2556 else if (ch <= 0xff) {
2557 PySys_WriteStderr("\\x%02x", ch);
2558 }
2559#if SIZEOF_WCHAR_T > 2
2560 else if (ch > 0xffff) {
2561 PySys_WriteStderr("\\U%08x", ch);
2562 }
2563#endif
2564 else {
2565 PySys_WriteStderr("\\u%04x", ch);
2566 }
2567 }
2568 PySys_WriteStderr("'");
2569}
2570
2571
2572/* Dump the Python path configuration into sys.stderr */
2573void
2574_Py_DumpPathConfig(PyThreadState *tstate)
2575{
2576 PyObject *exc_type, *exc_value, *exc_tb;
2577 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2578
2579 PySys_WriteStderr("Python path configuration:\n");
2580
2581#define DUMP_CONFIG(NAME, FIELD) \
2582 do { \
2583 PySys_WriteStderr(" " NAME " = "); \
2584 init_dump_ascii_wstr(config->FIELD); \
2585 PySys_WriteStderr("\n"); \
2586 } while (0)
2587
2588 PyConfig *config = &tstate->interp->config;
2589 DUMP_CONFIG("PYTHONHOME", home);
2590 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2591 DUMP_CONFIG("program name", program_name);
2592 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2593 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2594 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2595 PySys_WriteStderr(" import site = %i\n", config->site_import);
2596#undef DUMP_CONFIG
2597
2598#define DUMP_SYS(NAME) \
2599 do { \
2600 obj = PySys_GetObject(#NAME); \
2601 PySys_FormatStderr(" sys.%s = ", #NAME); \
2602 if (obj != NULL) { \
2603 PySys_FormatStderr("%A", obj); \
2604 } \
2605 else { \
2606 PySys_WriteStderr("(not set)"); \
2607 } \
2608 PySys_FormatStderr("\n"); \
2609 } while (0)
2610
2611 PyObject *obj;
2612 DUMP_SYS(_base_executable);
2613 DUMP_SYS(base_prefix);
2614 DUMP_SYS(base_exec_prefix);
2615 DUMP_SYS(executable);
2616 DUMP_SYS(prefix);
2617 DUMP_SYS(exec_prefix);
2618#undef DUMP_SYS
2619
2620 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2621 if (sys_path != NULL && PyList_Check(sys_path)) {
2622 PySys_WriteStderr(" sys.path = [\n");
2623 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2624 for (Py_ssize_t i=0; i < len; i++) {
2625 PyObject *path = PyList_GET_ITEM(sys_path, i);
2626 PySys_FormatStderr(" %A,\n", path);
2627 }
2628 PySys_WriteStderr(" ]\n");
2629 }
2630
2631 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2632}