blob: 9164c7cfc8e85b8c6aebfe67af5f24306799b6ca [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"
83"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
84"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
85static const char usage_6[] =
86"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Miss Islington (bot)076d0b92019-08-24 03:19:51 -070087" to seed the hashes of str and bytes objects. It can also be set to an\n"
88" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +010089" predictable seed.\n"
90"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
91" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
92" hooks.\n"
93"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
94" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
95" locale coercion and locale compatibility warnings on stderr.\n"
96"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
97" debugger. It can be set to the callable of your debugger of choice.\n"
98"PYTHONDEVMODE: enable the development mode.\n"
99"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
100
101#if defined(MS_WINDOWS)
102# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
103#else
104# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
105#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200106
107
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100108/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200109
Victor Stinner6c785c02018-08-01 17:56:14 +0200110/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200111 stdin and stdout error handler to "surrogateescape". */
112int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200113int Py_DebugFlag = 0; /* Needed by parser.c */
114int Py_VerboseFlag = 0; /* Needed by import.c */
115int Py_QuietFlag = 0; /* Needed by sysmodule.c */
116int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
117int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
118int Py_OptimizeFlag = 0; /* Needed by compile.c */
119int Py_NoSiteFlag = 0; /* Suppress 'import site' */
120int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
121int Py_FrozenFlag = 0; /* Needed by getpath.c */
122int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
123int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
124int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
125int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
126int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
127int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
128#ifdef MS_WINDOWS
129int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
130int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
131#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200132
133
Victor Stinner1075d162019-03-25 23:19:57 +0100134static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100135_Py_GetGlobalVariablesAsDict(void)
136{
137 PyObject *dict, *obj;
138
139 dict = PyDict_New();
140 if (dict == NULL) {
141 return NULL;
142 }
143
144#define SET_ITEM(KEY, EXPR) \
145 do { \
146 obj = (EXPR); \
147 if (obj == NULL) { \
148 return NULL; \
149 } \
150 int res = PyDict_SetItemString(dict, (KEY), obj); \
151 Py_DECREF(obj); \
152 if (res < 0) { \
153 goto fail; \
154 } \
155 } while (0)
156#define SET_ITEM_INT(VAR) \
157 SET_ITEM(#VAR, PyLong_FromLong(VAR))
158#define FROM_STRING(STR) \
159 ((STR != NULL) ? \
160 PyUnicode_FromString(STR) \
161 : (Py_INCREF(Py_None), Py_None))
162#define SET_ITEM_STR(VAR) \
163 SET_ITEM(#VAR, FROM_STRING(VAR))
164
165 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
166 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
167 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
168 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
169
170 SET_ITEM_INT(Py_UTF8Mode);
171 SET_ITEM_INT(Py_DebugFlag);
172 SET_ITEM_INT(Py_VerboseFlag);
173 SET_ITEM_INT(Py_QuietFlag);
174 SET_ITEM_INT(Py_InteractiveFlag);
175 SET_ITEM_INT(Py_InspectFlag);
176
177 SET_ITEM_INT(Py_OptimizeFlag);
178 SET_ITEM_INT(Py_NoSiteFlag);
179 SET_ITEM_INT(Py_BytesWarningFlag);
180 SET_ITEM_INT(Py_FrozenFlag);
181 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
182 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
183 SET_ITEM_INT(Py_NoUserSiteDirectory);
184 SET_ITEM_INT(Py_UnbufferedStdioFlag);
185 SET_ITEM_INT(Py_HashRandomizationFlag);
186 SET_ITEM_INT(Py_IsolatedFlag);
187
188#ifdef MS_WINDOWS
189 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
190 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
191#endif
192
193 return dict;
194
195fail:
196 Py_DECREF(dict);
197 return NULL;
198
199#undef FROM_STRING
200#undef SET_ITEM
201#undef SET_ITEM_INT
202#undef SET_ITEM_STR
203}
204
205
Victor Stinner331a6a52019-05-27 16:39:22 +0200206/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200207
Victor Stinner331a6a52019-05-27 16:39:22 +0200208PyStatus PyStatus_Ok(void)
209{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200210
Victor Stinner331a6a52019-05-27 16:39:22 +0200211PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200212{
Victor Stinner331a6a52019-05-27 16:39:22 +0200213 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner871ff772019-05-17 23:54:00 +0200214 .err_msg = err_msg};
215}
216
Victor Stinner331a6a52019-05-27 16:39:22 +0200217PyStatus PyStatus_NoMemory(void)
218{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200219
Victor Stinner331a6a52019-05-27 16:39:22 +0200220PyStatus PyStatus_Exit(int exitcode)
221{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200222
223
Victor Stinner331a6a52019-05-27 16:39:22 +0200224int PyStatus_IsError(PyStatus status)
225{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200226
Victor Stinner331a6a52019-05-27 16:39:22 +0200227int PyStatus_IsExit(PyStatus status)
228{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200229
Victor Stinner331a6a52019-05-27 16:39:22 +0200230int PyStatus_Exception(PyStatus status)
231{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200232
233
Victor Stinner331a6a52019-05-27 16:39:22 +0200234/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100235
236#ifndef NDEBUG
237int
Victor Stinner331a6a52019-05-27 16:39:22 +0200238_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100239{
240 assert(list->length >= 0);
241 if (list->length != 0) {
242 assert(list->items != NULL);
243 }
244 for (Py_ssize_t i = 0; i < list->length; i++) {
245 assert(list->items[i] != NULL);
246 }
247 return 1;
248}
249#endif /* Py_DEBUG */
250
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100251
Victor Stinner6c785c02018-08-01 17:56:14 +0200252void
Victor Stinner331a6a52019-05-27 16:39:22 +0200253_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200254{
Victor Stinner331a6a52019-05-27 16:39:22 +0200255 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100256 for (Py_ssize_t i=0; i < list->length; i++) {
257 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200258 }
Victor Stinner74f65682019-03-15 15:08:05 +0100259 PyMem_RawFree(list->items);
260 list->length = 0;
261 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200262}
263
264
Victor Stinner74f65682019-03-15 15:08:05 +0100265int
Victor Stinner331a6a52019-05-27 16:39:22 +0200266_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200267{
Victor Stinner331a6a52019-05-27 16:39:22 +0200268 assert(_PyWideStringList_CheckConsistency(list));
269 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100270
271 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200272 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100273 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300274 }
Victor Stinner74f65682019-03-15 15:08:05 +0100275
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -0700276 PyWideStringList copy = _PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100277
278 size_t size = list2->length * sizeof(list2->items[0]);
279 copy.items = PyMem_RawMalloc(size);
280 if (copy.items == NULL) {
281 return -1;
282 }
283
284 for (Py_ssize_t i=0; i < list2->length; i++) {
285 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
286 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200287 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100288 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200289 }
Victor Stinner74f65682019-03-15 15:08:05 +0100290 copy.items[i] = item;
291 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200292 }
Victor Stinner74f65682019-03-15 15:08:05 +0100293
Victor Stinner331a6a52019-05-27 16:39:22 +0200294 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100295 *list = copy;
296 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200297}
298
299
Victor Stinner331a6a52019-05-27 16:39:22 +0200300PyStatus
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700301PyWideStringList_Insert(PyWideStringList *list,
302 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100303{
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700304 Py_ssize_t len = list->length;
305 if (len == PY_SSIZE_T_MAX) {
Kyle Stanley24b5b362019-07-21 22:48:45 -0400306 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200307 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100308 }
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700309 if (index < 0) {
310 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
311 }
312 if (index > len) {
313 index = len;
314 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100315
Victor Stinner74f65682019-03-15 15:08:05 +0100316 wchar_t *item2 = _PyMem_RawWcsdup(item);
317 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200318 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100319 }
Victor Stinner74f65682019-03-15 15:08:05 +0100320
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700321 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100322 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
323 if (items2 == NULL) {
324 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200325 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100326 }
327
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700328 if (index < len) {
329 memmove(&items2[index + 1],
330 &items2[index],
331 (len - index) * sizeof(items2[0]));
332 }
333
334 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100335 list->items = items2;
336 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200337 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100338}
339
340
Victor Stinner331a6a52019-05-27 16:39:22 +0200341PyStatus
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700342PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
343{
344 return PyWideStringList_Insert(list, list->length, item);
345}
346
347
348PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200349_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100350{
351 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200352 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
353 if (_PyStatus_EXCEPTION(status)) {
354 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100355 }
356 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200357 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100358}
359
360
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100361static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200362_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100363{
364 for (Py_ssize_t i = 0; i < list->length; i++) {
365 if (wcscmp(list->items[i], item) == 0) {
366 return 1;
367 }
368 }
369 return 0;
370}
371
372
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100373PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200374_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100375{
Victor Stinner331a6a52019-05-27 16:39:22 +0200376 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100377
Victor Stinner74f65682019-03-15 15:08:05 +0100378 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100379 if (pylist == NULL) {
380 return NULL;
381 }
382
Victor Stinner74f65682019-03-15 15:08:05 +0100383 for (Py_ssize_t i = 0; i < list->length; i++) {
384 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
385 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100386 Py_DECREF(pylist);
387 return NULL;
388 }
Victor Stinner74f65682019-03-15 15:08:05 +0100389 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100390 }
391 return pylist;
392}
393
394
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100395/* --- Py_SetStandardStreamEncoding() ----------------------------- */
396
Victor Stinner124b9eb2018-08-29 01:29:06 +0200397/* Helper to allow an embedding application to override the normal
398 * mechanism that attempts to figure out an appropriate IO encoding
399 */
400
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200401static char *_Py_StandardStreamEncoding = NULL;
402static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200403
404int
405Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
406{
407 if (Py_IsInitialized()) {
408 /* This is too late to have any effect */
409 return -1;
410 }
411
412 int res = 0;
413
414 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
415 but Py_Initialize() can change the allocator. Use a known allocator
416 to be able to release the memory later. */
417 PyMemAllocatorEx old_alloc;
418 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
419
420 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
421 * initialised yet.
422 *
423 * However, the raw memory allocators are initialised appropriately
424 * as C static variables, so _PyMem_RawStrdup is OK even though
425 * Py_Initialize hasn't been called yet.
426 */
427 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200428 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200429 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
430 if (!_Py_StandardStreamEncoding) {
431 res = -2;
432 goto done;
433 }
434 }
435 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200436 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200437 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
438 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200439 PyMem_RawFree(_Py_StandardStreamEncoding);
440 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200441 res = -3;
442 goto done;
443 }
444 }
445#ifdef MS_WINDOWS
446 if (_Py_StandardStreamEncoding) {
447 /* Overriding the stream encoding implies legacy streams */
448 Py_LegacyWindowsStdioFlag = 1;
449 }
450#endif
451
452done:
453 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
454
455 return res;
456}
457
458
459void
460_Py_ClearStandardStreamEncoding(void)
461{
462 /* Use the same allocator than Py_SetStandardStreamEncoding() */
463 PyMemAllocatorEx old_alloc;
464 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
465
466 /* We won't need them anymore. */
467 if (_Py_StandardStreamEncoding) {
468 PyMem_RawFree(_Py_StandardStreamEncoding);
469 _Py_StandardStreamEncoding = NULL;
470 }
471 if (_Py_StandardStreamErrors) {
472 PyMem_RawFree(_Py_StandardStreamErrors);
473 _Py_StandardStreamErrors = NULL;
474 }
475
476 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
477}
478
479
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100480/* --- Py_GetArgcArgv() ------------------------------------------- */
481
482/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200483static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100484
485
486void
487_Py_ClearArgcArgv(void)
488{
489 PyMemAllocatorEx old_alloc;
490 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
491
Victor Stinner331a6a52019-05-27 16:39:22 +0200492 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100493
494 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
495}
496
497
Victor Stinner4fffd382019-03-06 01:44:31 +0100498static int
Victor Stinner74f65682019-03-15 15:08:05 +0100499_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100500{
Victor Stinner331a6a52019-05-27 16:39:22 +0200501 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100502 int res;
503
504 PyMemAllocatorEx old_alloc;
505 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
506
Victor Stinner331a6a52019-05-27 16:39:22 +0200507 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100508
509 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
510 return res;
511}
512
513
514/* Make the *original* argc/argv available to other modules.
515 This is rare, but it is needed by the secureware extension. */
516void
517Py_GetArgcArgv(int *argc, wchar_t ***argv)
518{
Victor Stinner74f65682019-03-15 15:08:05 +0100519 *argc = (int)orig_argv.length;
520 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100521}
522
523
Victor Stinner331a6a52019-05-27 16:39:22 +0200524/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100525
526#define DECODE_LOCALE_ERR(NAME, LEN) \
527 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200528 ? _PyStatus_ERR("cannot decode " NAME) \
529 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100530
Victor Stinner6e128382019-09-28 04:50:43 +0200531
Victor Stinner6c785c02018-08-01 17:56:14 +0200532/* Free memory allocated in config, but don't clear all attributes */
533void
Victor Stinner331a6a52019-05-27 16:39:22 +0200534PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200535{
536#define CLEAR(ATTR) \
537 do { \
538 PyMem_RawFree(ATTR); \
539 ATTR = NULL; \
540 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200541
542 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200543 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200544 CLEAR(config->home);
545 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200546
Victor Stinner331a6a52019-05-27 16:39:22 +0200547 _PyWideStringList_Clear(&config->argv);
548 _PyWideStringList_Clear(&config->warnoptions);
549 _PyWideStringList_Clear(&config->xoptions);
550 _PyWideStringList_Clear(&config->module_search_paths);
551 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200552
553 CLEAR(config->executable);
Steve Dower323e7432019-06-29 14:28:59 -0700554 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200555 CLEAR(config->prefix);
556 CLEAR(config->base_prefix);
557 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200558 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200559
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200560 CLEAR(config->filesystem_encoding);
561 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200562 CLEAR(config->stdio_encoding);
563 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100564 CLEAR(config->run_command);
565 CLEAR(config->run_module);
566 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400567 CLEAR(config->check_hash_pycs_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200568#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200569}
570
571
Victor Stinner6e128382019-09-28 04:50:43 +0200572PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200573_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200574{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200575 memset(config, 0, sizeof(*config));
Victor Stinner6e128382019-09-28 04:50:43 +0200576
Victor Stinner022be022019-05-22 23:58:50 +0200577 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200578 config->isolated = -1;
579 config->use_environment = -1;
580 config->dev_mode = -1;
581 config->install_signal_handlers = 1;
582 config->use_hash_seed = -1;
583 config->faulthandler = -1;
584 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200585 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200586 config->parse_argv = 0;
587 config->site_import = -1;
588 config->bytes_warning = -1;
589 config->inspect = -1;
590 config->interactive = -1;
591 config->optimization_level = -1;
592 config->parser_debug= -1;
593 config->write_bytecode = -1;
594 config->verbose = -1;
595 config->quiet = -1;
596 config->user_site_directory = -1;
597 config->configure_c_stdio = 0;
598 config->buffered_stdio = -1;
599 config->_install_importlib = 1;
600 config->check_hash_pycs_mode = NULL;
601 config->pathconfig_warnings = -1;
602 config->_init_main = 1;
603#ifdef MS_WINDOWS
604 config->legacy_windows_stdio = -1;
605#endif
Victor Stinner6e128382019-09-28 04:50:43 +0200606 return _PyStatus_OK();
Victor Stinnerbab0db62019-05-18 03:21:27 +0200607}
608
609
Victor Stinner6e128382019-09-28 04:50:43 +0200610static PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200611config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200612{
Victor Stinner6e128382019-09-28 04:50:43 +0200613 PyStatus status = _PyConfig_InitCompatConfig(config);
614 if (_PyStatus_EXCEPTION(status)) {
615 return status;
616 }
Victor Stinnerbab0db62019-05-18 03:21:27 +0200617
618 config->isolated = 0;
619 config->use_environment = 1;
620 config->site_import = 1;
621 config->bytes_warning = 0;
622 config->inspect = 0;
623 config->interactive = 0;
624 config->optimization_level = 0;
625 config->parser_debug= 0;
626 config->write_bytecode = 1;
627 config->verbose = 0;
628 config->quiet = 0;
629 config->user_site_directory = 1;
630 config->buffered_stdio = 1;
631 config->pathconfig_warnings = 1;
632#ifdef MS_WINDOWS
633 config->legacy_windows_stdio = 0;
634#endif
Victor Stinner6e128382019-09-28 04:50:43 +0200635 return _PyStatus_OK();
Victor Stinnercab5d072019-05-17 19:01:14 +0200636}
637
638
Victor Stinner331a6a52019-05-27 16:39:22 +0200639PyStatus
640PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200641{
Victor Stinner6e128382019-09-28 04:50:43 +0200642 PyStatus status = config_init_defaults(config);
643 if (_PyStatus_EXCEPTION(status)) {
644 _PyStatus_UPDATE_FUNC(status);
645 return status;
646 }
Victor Stinnercab5d072019-05-17 19:01:14 +0200647
Victor Stinner022be022019-05-22 23:58:50 +0200648 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200649 config->configure_c_stdio = 1;
650 config->parse_argv = 1;
651
Victor Stinner331a6a52019-05-27 16:39:22 +0200652 return _PyStatus_OK();
Victor Stinnercab5d072019-05-17 19:01:14 +0200653}
654
655
Victor Stinner331a6a52019-05-27 16:39:22 +0200656PyStatus
657PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200658{
Victor Stinner6e128382019-09-28 04:50:43 +0200659 PyStatus status = config_init_defaults(config);
660 if (_PyStatus_EXCEPTION(status)) {
661 _PyStatus_UPDATE_FUNC(status);
662 return status;
663 }
Victor Stinnercab5d072019-05-17 19:01:14 +0200664
Victor Stinner022be022019-05-22 23:58:50 +0200665 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200666 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200667 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200668 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200669 config->dev_mode = 0;
670 config->install_signal_handlers = 0;
671 config->use_hash_seed = 0;
672 config->faulthandler = 0;
673 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200674 config->pathconfig_warnings = 0;
675#ifdef MS_WINDOWS
676 config->legacy_windows_stdio = 0;
677#endif
678
Victor Stinner331a6a52019-05-27 16:39:22 +0200679 return _PyStatus_OK();
Victor Stinnercab5d072019-05-17 19:01:14 +0200680}
681
682
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200683/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200684PyStatus
685PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200686{
Victor Stinner331a6a52019-05-27 16:39:22 +0200687 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
688 if (_PyStatus_EXCEPTION(status)) {
689 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200690 }
691
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200692 wchar_t *str2;
693 if (str != NULL) {
694 str2 = _PyMem_RawWcsdup(str);
695 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200696 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200697 }
698 }
699 else {
700 str2 = NULL;
701 }
702 PyMem_RawFree(*config_str);
703 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200704 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200705}
706
707
Victor Stinner331a6a52019-05-27 16:39:22 +0200708static PyStatus
709config_set_bytes_string(PyConfig *config, wchar_t **config_str,
710 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200711{
Victor Stinner331a6a52019-05-27 16:39:22 +0200712 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
713 if (_PyStatus_EXCEPTION(status)) {
714 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400715 }
716
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200717 wchar_t *str2;
718 if (str != NULL) {
719 size_t len;
720 str2 = Py_DecodeLocale(str, &len);
721 if (str2 == NULL) {
722 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200723 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200724 }
725 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200726 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200727 }
728 }
729 }
730 else {
731 str2 = NULL;
732 }
733 PyMem_RawFree(*config_str);
734 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200735 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200736}
737
738
Victor Stinner331a6a52019-05-27 16:39:22 +0200739#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
740 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400741
742
Victor Stinner70005ac2019-05-02 15:25:34 -0400743/* Decode str using Py_DecodeLocale() and set the result into *config_str.
744 Pre-initialize Python if needed to ensure that encodings are properly
745 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200746PyStatus
747PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200748 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400749{
Victor Stinner331a6a52019-05-27 16:39:22 +0200750 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400751}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200752
753
Victor Stinner331a6a52019-05-27 16:39:22 +0200754PyStatus
755_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200756{
Victor Stinner331a6a52019-05-27 16:39:22 +0200757 PyStatus status;
Victor Stinner6e128382019-09-28 04:50:43 +0200758
Victor Stinner331a6a52019-05-27 16:39:22 +0200759 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200760
761#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200762#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200763 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200764 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
765 if (_PyStatus_EXCEPTION(status)) { \
766 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200767 } \
768 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100769#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200770 do { \
Miss Islington (bot)96f581c2019-07-01 10:39:58 -0700771 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200772 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200773 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200774 } while (0)
775
Victor Stinner6d1c4672019-05-20 11:02:00 +0200776 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100777 COPY_ATTR(isolated);
778 COPY_ATTR(use_environment);
779 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200780 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200781 COPY_ATTR(use_hash_seed);
782 COPY_ATTR(hash_seed);
783 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200784 COPY_ATTR(faulthandler);
785 COPY_ATTR(tracemalloc);
786 COPY_ATTR(import_time);
787 COPY_ATTR(show_ref_count);
788 COPY_ATTR(show_alloc_count);
789 COPY_ATTR(dump_refs);
790 COPY_ATTR(malloc_stats);
791
Victor Stinner124b9eb2018-08-29 01:29:06 +0200792 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200793 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200794 COPY_WSTR_ATTR(home);
795 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200796
Victor Stinnerae239f62019-05-16 17:02:56 +0200797 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100798 COPY_WSTRLIST(argv);
799 COPY_WSTRLIST(warnoptions);
800 COPY_WSTRLIST(xoptions);
801 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200802 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200803
Victor Stinner124b9eb2018-08-29 01:29:06 +0200804 COPY_WSTR_ATTR(executable);
Steve Dower323e7432019-06-29 14:28:59 -0700805 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200806 COPY_WSTR_ATTR(prefix);
807 COPY_WSTR_ATTR(base_prefix);
808 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200809 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200810
Victor Stinner6c785c02018-08-01 17:56:14 +0200811 COPY_ATTR(site_import);
812 COPY_ATTR(bytes_warning);
813 COPY_ATTR(inspect);
814 COPY_ATTR(interactive);
815 COPY_ATTR(optimization_level);
816 COPY_ATTR(parser_debug);
817 COPY_ATTR(write_bytecode);
818 COPY_ATTR(verbose);
819 COPY_ATTR(quiet);
820 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200821 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200822 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400823 COPY_WSTR_ATTR(filesystem_encoding);
824 COPY_WSTR_ATTR(filesystem_errors);
825 COPY_WSTR_ATTR(stdio_encoding);
826 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200827#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200828 COPY_ATTR(legacy_windows_stdio);
829#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100830 COPY_ATTR(skip_source_first_line);
831 COPY_WSTR_ATTR(run_command);
832 COPY_WSTR_ATTR(run_module);
833 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400834 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200835 COPY_ATTR(pathconfig_warnings);
836 COPY_ATTR(_init_main);
Victor Stinner6c785c02018-08-01 17:56:14 +0200837
838#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200839#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200840#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200841 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200842}
843
844
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100845static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200846config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100847{
848 PyObject *dict;
849
850 dict = PyDict_New();
851 if (dict == NULL) {
852 return NULL;
853 }
854
855#define SET_ITEM(KEY, EXPR) \
856 do { \
857 PyObject *obj = (EXPR); \
858 if (obj == NULL) { \
859 goto fail; \
860 } \
861 int res = PyDict_SetItemString(dict, (KEY), obj); \
862 Py_DECREF(obj); \
863 if (res < 0) { \
864 goto fail; \
865 } \
866 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100867#define SET_ITEM_INT(ATTR) \
868 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
869#define SET_ITEM_UINT(ATTR) \
870 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100871#define FROM_WSTRING(STR) \
872 ((STR != NULL) ? \
873 PyUnicode_FromWideChar(STR, -1) \
874 : (Py_INCREF(Py_None), Py_None))
875#define SET_ITEM_WSTR(ATTR) \
876 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
877#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200878 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100879
Victor Stinner6d1c4672019-05-20 11:02:00 +0200880 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100881 SET_ITEM_INT(isolated);
882 SET_ITEM_INT(use_environment);
883 SET_ITEM_INT(dev_mode);
884 SET_ITEM_INT(install_signal_handlers);
885 SET_ITEM_INT(use_hash_seed);
886 SET_ITEM_UINT(hash_seed);
887 SET_ITEM_INT(faulthandler);
888 SET_ITEM_INT(tracemalloc);
889 SET_ITEM_INT(import_time);
890 SET_ITEM_INT(show_ref_count);
891 SET_ITEM_INT(show_alloc_count);
892 SET_ITEM_INT(dump_refs);
893 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400894 SET_ITEM_WSTR(filesystem_encoding);
895 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100896 SET_ITEM_WSTR(pycache_prefix);
897 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200898 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100899 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100900 SET_ITEM_WSTRLIST(xoptions);
901 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200902 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100903 SET_ITEM_WSTR(home);
904 SET_ITEM_WSTRLIST(module_search_paths);
905 SET_ITEM_WSTR(executable);
Steve Dower323e7432019-06-29 14:28:59 -0700906 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100907 SET_ITEM_WSTR(prefix);
908 SET_ITEM_WSTR(base_prefix);
909 SET_ITEM_WSTR(exec_prefix);
910 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100911 SET_ITEM_INT(site_import);
912 SET_ITEM_INT(bytes_warning);
913 SET_ITEM_INT(inspect);
914 SET_ITEM_INT(interactive);
915 SET_ITEM_INT(optimization_level);
916 SET_ITEM_INT(parser_debug);
917 SET_ITEM_INT(write_bytecode);
918 SET_ITEM_INT(verbose);
919 SET_ITEM_INT(quiet);
920 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200921 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100922 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400923 SET_ITEM_WSTR(stdio_encoding);
924 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100925#ifdef MS_WINDOWS
926 SET_ITEM_INT(legacy_windows_stdio);
927#endif
928 SET_ITEM_INT(skip_source_first_line);
929 SET_ITEM_WSTR(run_command);
930 SET_ITEM_WSTR(run_module);
931 SET_ITEM_WSTR(run_filename);
932 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400933 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200934 SET_ITEM_INT(pathconfig_warnings);
935 SET_ITEM_INT(_init_main);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100936
937 return dict;
938
939fail:
940 Py_DECREF(dict);
941 return NULL;
942
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100943#undef FROM_WSTRING
944#undef SET_ITEM
945#undef SET_ITEM_INT
946#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100947#undef SET_ITEM_WSTR
948#undef SET_ITEM_WSTRLIST
949}
950
951
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100952static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200953config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200954{
Victor Stinner20004952019-03-26 02:31:11 +0100955 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200956}
957
958
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100959/* Get a copy of the environment variable as wchar_t*.
960 Return 0 on success, but *dest can be NULL.
961 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200962static PyStatus
963config_get_env_dup(PyConfig *config,
964 wchar_t **dest,
965 wchar_t *wname, char *name,
966 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200967{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200968 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100969 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200970
Victor Stinner20004952019-03-26 02:31:11 +0100971 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200972 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200973 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200974 }
975
976#ifdef MS_WINDOWS
977 const wchar_t *var = _wgetenv(wname);
978 if (!var || var[0] == '\0') {
979 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200980 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200981 }
982
Victor Stinner331a6a52019-05-27 16:39:22 +0200983 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +0200984#else
985 const char *var = getenv(name);
986 if (!var || var[0] == '\0') {
987 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200988 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200989 }
990
Victor Stinner331a6a52019-05-27 16:39:22 +0200991 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +0200992#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200993}
994
995
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200996#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200997 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200998
999
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001000static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001001config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001002{
Victor Stinner022be022019-05-22 23:58:50 +02001003 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1004 /* Python and Isolated configuration ignore global variables */
1005 return;
1006 }
1007
Victor Stinner6c785c02018-08-01 17:56:14 +02001008#define COPY_FLAG(ATTR, VALUE) \
1009 if (config->ATTR == -1) { \
1010 config->ATTR = VALUE; \
1011 }
1012#define COPY_NOT_FLAG(ATTR, VALUE) \
1013 if (config->ATTR == -1) { \
1014 config->ATTR = !(VALUE); \
1015 }
1016
Victor Stinner20004952019-03-26 02:31:11 +01001017 COPY_FLAG(isolated, Py_IsolatedFlag);
1018 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001019 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1020 COPY_FLAG(inspect, Py_InspectFlag);
1021 COPY_FLAG(interactive, Py_InteractiveFlag);
1022 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1023 COPY_FLAG(parser_debug, Py_DebugFlag);
1024 COPY_FLAG(verbose, Py_VerboseFlag);
1025 COPY_FLAG(quiet, Py_QuietFlag);
1026#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001027 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1028#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001029 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001030
Victor Stinner6c785c02018-08-01 17:56:14 +02001031 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1032 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1033 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1034 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1035
Victor Stinner6c785c02018-08-01 17:56:14 +02001036#undef COPY_FLAG
1037#undef COPY_NOT_FLAG
1038}
1039
1040
1041/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001042static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001043config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001044{
1045#define COPY_FLAG(ATTR, VAR) \
1046 if (config->ATTR != -1) { \
1047 VAR = config->ATTR; \
1048 }
1049#define COPY_NOT_FLAG(ATTR, VAR) \
1050 if (config->ATTR != -1) { \
1051 VAR = !config->ATTR; \
1052 }
1053
Victor Stinner20004952019-03-26 02:31:11 +01001054 COPY_FLAG(isolated, Py_IsolatedFlag);
1055 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001056 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1057 COPY_FLAG(inspect, Py_InspectFlag);
1058 COPY_FLAG(interactive, Py_InteractiveFlag);
1059 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1060 COPY_FLAG(parser_debug, Py_DebugFlag);
1061 COPY_FLAG(verbose, Py_VerboseFlag);
1062 COPY_FLAG(quiet, Py_QuietFlag);
1063#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001064 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1065#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001066 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001067
Victor Stinner6c785c02018-08-01 17:56:14 +02001068 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1069 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1070 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1071 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1072
Victor Stinner6c785c02018-08-01 17:56:14 +02001073 /* Random or non-zero hash seed */
1074 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1075 config->hash_seed != 0);
1076
1077#undef COPY_FLAG
1078#undef COPY_NOT_FLAG
1079}
1080
1081
1082/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1083 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001084static PyStatus
1085config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001086{
Victor Stinner331a6a52019-05-27 16:39:22 +02001087 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001088
Victor Stinner6c785c02018-08-01 17:56:14 +02001089 /* If Py_SetProgramName() was called, use its value */
1090 const wchar_t *program_name = _Py_path_config.program_name;
1091 if (program_name != NULL) {
1092 config->program_name = _PyMem_RawWcsdup(program_name);
1093 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001094 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001095 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001096 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001097 }
1098
1099#ifdef __APPLE__
1100 /* On MacOS X, when the Python interpreter is embedded in an
1101 application bundle, it gets executed by a bootstrapping script
1102 that does os.execve() with an argv[0] that's different from the
1103 actual Python executable. This is needed to keep the Finder happy,
1104 or rather, to work around Apple's overly strict requirements of
1105 the process name. However, we still need a usable sys.executable,
1106 so the actual executable path is passed in an environment variable.
1107 See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
1108 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001109 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001110 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001111 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1112 "PYTHONEXECUTABLE 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#ifdef WITH_NEXT_FRAMEWORK
1119 else {
1120 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1121 if (pyvenv_launcher && *pyvenv_launcher) {
1122 /* Used by Mac/Tools/pythonw.c to forward
1123 * the argv0 of the stub executable
1124 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001125 status = CONFIG_SET_BYTES_STR(config,
1126 &config->program_name,
1127 pyvenv_launcher,
1128 "__PYVENV_LAUNCHER__ environment variable");
1129 if (_PyStatus_EXCEPTION(status)) {
1130 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001131 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001132 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001133 }
1134 }
1135#endif /* WITH_NEXT_FRAMEWORK */
1136#endif /* __APPLE__ */
1137
Victor Stinnerfed02e12019-05-17 11:12:09 +02001138 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001139 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001140 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1141 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1142 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001143 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001144 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001145 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001146 }
1147
Victor Stinnerfed02e12019-05-17 11:12:09 +02001148 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001149#ifdef MS_WINDOWS
1150 const wchar_t *default_program_name = L"python";
1151#else
1152 const wchar_t *default_program_name = L"python3";
1153#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001154 status = PyConfig_SetString(config, &config->program_name,
1155 default_program_name);
1156 if (_PyStatus_EXCEPTION(status)) {
1157 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001158 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001159 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001160}
1161
Victor Stinner331a6a52019-05-27 16:39:22 +02001162static PyStatus
1163config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001164{
1165 assert(config->executable == NULL);
1166
1167 /* If Py_SetProgramFullPath() was called, use its value */
1168 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1169 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001170 PyStatus status = PyConfig_SetString(config,
1171 &config->executable,
1172 program_full_path);
1173 if (_PyStatus_EXCEPTION(status)) {
1174 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001175 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001176 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001177 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001178 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001179}
Victor Stinner6c785c02018-08-01 17:56:14 +02001180
Victor Stinner4fffd382019-03-06 01:44:31 +01001181
Victor Stinner6c785c02018-08-01 17:56:14 +02001182static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001183config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001184{
Victor Stinner74f65682019-03-15 15:08:05 +01001185 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001186}
1187
1188
Victor Stinner331a6a52019-05-27 16:39:22 +02001189static PyStatus
1190config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001191{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001192 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001193
1194 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001195 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001196 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001197 PyStatus status = PyConfig_SetString(config, &config->home, home);
1198 if (_PyStatus_EXCEPTION(status)) {
1199 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001200 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001201 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001202 }
1203
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001204 return CONFIG_GET_ENV_DUP(config, &config->home,
1205 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001206}
1207
1208
Victor Stinner331a6a52019-05-27 16:39:22 +02001209static PyStatus
1210config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001211{
Victor Stinner331a6a52019-05-27 16:39:22 +02001212 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001213
1214 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1215 /* Convert a text seed to a numeric one */
1216 if (seed_text && strcmp(seed_text, "random") != 0) {
1217 const char *endptr = seed_text;
1218 unsigned long seed;
1219 errno = 0;
1220 seed = strtoul(seed_text, (char **)&endptr, 10);
1221 if (*endptr != '\0'
1222 || seed > 4294967295UL
1223 || (errno == ERANGE && seed == ULONG_MAX))
1224 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001225 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001226 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001227 }
1228 /* Use a specific hash */
1229 config->use_hash_seed = 1;
1230 config->hash_seed = seed;
1231 }
1232 else {
1233 /* Use a random hash */
1234 config->use_hash_seed = 0;
1235 config->hash_seed = 0;
1236 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001237 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001238}
1239
1240
Victor Stinner6c785c02018-08-01 17:56:14 +02001241static int
1242config_wstr_to_int(const wchar_t *wstr, int *result)
1243{
1244 const wchar_t *endptr = wstr;
1245 errno = 0;
1246 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1247 if (*endptr != '\0' || errno == ERANGE) {
1248 return -1;
1249 }
1250 if (value < INT_MIN || value > INT_MAX) {
1251 return -1;
1252 }
1253
1254 *result = (int)value;
1255 return 0;
1256}
1257
1258
Victor Stinner331a6a52019-05-27 16:39:22 +02001259static PyStatus
1260config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001261{
Victor Stinner331a6a52019-05-27 16:39:22 +02001262 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001263 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001264
Victor Stinner6c785c02018-08-01 17:56:14 +02001265 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001266 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1267 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1268 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1269 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001270
1271 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001272 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001273 if (dont_write_bytecode) {
1274 config->write_bytecode = 0;
1275 }
1276
1277 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001278 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001279 if (no_user_site_directory) {
1280 config->user_site_directory = 0;
1281 }
1282
1283 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001284 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001285 if (unbuffered_stdio) {
1286 config->buffered_stdio = 0;
1287 }
1288
1289#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001290 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001291 "PYTHONLEGACYWINDOWSSTDIO");
1292#endif
1293
Victor Stinner331a6a52019-05-27 16:39:22 +02001294 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001295 config->dump_refs = 1;
1296 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001297 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001298 config->malloc_stats = 1;
1299 }
1300
Victor Stinner331a6a52019-05-27 16:39:22 +02001301 if (config->pythonpath_env == NULL) {
1302 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1303 L"PYTHONPATH", "PYTHONPATH");
1304 if (_PyStatus_EXCEPTION(status)) {
1305 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001306 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001307 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001308
1309 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001310 status = config_init_hash_seed(config);
1311 if (_PyStatus_EXCEPTION(status)) {
1312 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001313 }
1314 }
1315
Victor Stinner331a6a52019-05-27 16:39:22 +02001316 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001317}
1318
1319
Victor Stinner331a6a52019-05-27 16:39:22 +02001320static PyStatus
1321config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001322{
1323 int nframe;
1324 int valid;
1325
Victor Stinner331a6a52019-05-27 16:39:22 +02001326 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001327 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001328 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001329 valid = (nframe >= 0);
1330 }
1331 else {
1332 valid = 0;
1333 }
1334 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001335 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001336 }
1337 config->tracemalloc = nframe;
1338 }
1339
1340 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1341 if (xoption) {
1342 const wchar_t *sep = wcschr(xoption, L'=');
1343 if (sep) {
1344 if (!config_wstr_to_int(sep + 1, &nframe)) {
1345 valid = (nframe >= 0);
1346 }
1347 else {
1348 valid = 0;
1349 }
1350 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001351 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1352 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001353 }
1354 }
1355 else {
1356 /* -X tracemalloc behaves as -X tracemalloc=1 */
1357 nframe = 1;
1358 }
1359 config->tracemalloc = nframe;
1360 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001361 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001362}
1363
1364
Victor Stinner331a6a52019-05-27 16:39:22 +02001365static PyStatus
1366config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001367{
1368 assert(config->pycache_prefix == NULL);
1369
1370 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1371 if (xoption) {
1372 const wchar_t *sep = wcschr(xoption, L'=');
1373 if (sep && wcslen(sep) > 1) {
1374 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1375 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001376 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001377 }
1378 }
1379 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001380 // PYTHONPYCACHEPREFIX env var ignored
1381 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001382 config->pycache_prefix = NULL;
1383 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001384 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001385 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001386
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001387 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1388 L"PYTHONPYCACHEPREFIX",
1389 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001390}
1391
1392
Victor Stinner331a6a52019-05-27 16:39:22 +02001393static PyStatus
1394config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001395{
1396 /* More complex options configured by env var and -X option */
1397 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001398 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001399 || config_get_xoption(config, L"faulthandler")) {
1400 config->faulthandler = 1;
1401 }
1402 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001403 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001404 || config_get_xoption(config, L"importtime")) {
1405 config->import_time = 1;
1406 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001407
Victor Stinner331a6a52019-05-27 16:39:22 +02001408 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001409 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001410 status = config_init_tracemalloc(config);
1411 if (_PyStatus_EXCEPTION(status)) {
1412 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001413 }
1414 }
1415
1416 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001417 status = config_init_pycache_prefix(config);
1418 if (_PyStatus_EXCEPTION(status)) {
1419 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001420 }
1421 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001422 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001423}
1424
1425
Victor Stinner709d23d2019-05-02 14:56:30 -04001426static const wchar_t *
Victor Stinner331a6a52019-05-27 16:39:22 +02001427config_get_stdio_errors(const PyConfig *config)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001428{
1429#ifndef MS_WINDOWS
1430 const char *loc = setlocale(LC_CTYPE, NULL);
1431 if (loc != NULL) {
1432 /* surrogateescape is the default in the legacy C and POSIX locales */
1433 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001434 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001435 }
1436
1437#ifdef PY_COERCE_C_LOCALE
1438 /* surrogateescape is the default in locale coercion target locales */
1439 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001440 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001441 }
1442#endif
1443 }
1444
Victor Stinner709d23d2019-05-02 14:56:30 -04001445 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001446#else
1447 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001448 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001449#endif
1450}
1451
1452
Victor Stinner331a6a52019-05-27 16:39:22 +02001453static PyStatus
1454config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001455{
1456#ifdef MS_WINDOWS
1457 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001458 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001459 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001460#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001461 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001462#else
1463 const char *encoding = nl_langinfo(CODESET);
1464 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001465 return _PyStatus_ERR("failed to get the locale encoding: "
1466 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001467 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001468 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001469 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001470 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001471 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001472#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001473}
1474
1475
Victor Stinner331a6a52019-05-27 16:39:22 +02001476static PyStatus
1477config_init_stdio_encoding(PyConfig *config,
1478 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001479{
Victor Stinner331a6a52019-05-27 16:39:22 +02001480 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001481
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001482 /* If Py_SetStandardStreamEncoding() have been called, use these
1483 parameters. */
1484 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001485 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1486 _Py_StandardStreamEncoding,
1487 "_Py_StandardStreamEncoding");
1488 if (_PyStatus_EXCEPTION(status)) {
1489 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001490 }
1491 }
1492
1493 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001494 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1495 _Py_StandardStreamErrors,
1496 "_Py_StandardStreamErrors");
1497 if (_PyStatus_EXCEPTION(status)) {
1498 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001499 }
1500 }
1501
1502 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001503 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001504 }
1505
1506 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001507 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001508 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001509 char *pythonioencoding = _PyMem_RawStrdup(opt);
1510 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001511 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001512 }
1513
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001514 char *errors = strchr(pythonioencoding, ':');
1515 if (errors) {
1516 *errors = '\0';
1517 errors++;
1518 if (!errors[0]) {
1519 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001520 }
1521 }
1522
1523 /* Does PYTHONIOENCODING contain an encoding? */
1524 if (pythonioencoding[0]) {
1525 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001526 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1527 pythonioencoding,
1528 "PYTHONIOENCODING environment variable");
1529 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001530 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001531 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001532 }
1533 }
1534
1535 /* If the encoding is set but not the error handler,
1536 use "strict" error handler by default.
1537 PYTHONIOENCODING=latin1 behaves as
1538 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001539 if (!errors) {
1540 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001541 }
1542 }
1543
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001544 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001545 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1546 errors,
1547 "PYTHONIOENCODING environment variable");
1548 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001549 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001550 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001551 }
1552 }
1553
1554 PyMem_RawFree(pythonioencoding);
1555 }
1556
1557 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001558 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001559 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001560 status = PyConfig_SetString(config, &config->stdio_encoding,
1561 L"utf-8");
1562 if (_PyStatus_EXCEPTION(status)) {
1563 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001564 }
1565 }
1566 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001567 status = PyConfig_SetString(config, &config->stdio_errors,
1568 L"surrogateescape");
1569 if (_PyStatus_EXCEPTION(status)) {
1570 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001571 }
1572 }
1573 }
1574
1575 /* Choose the default error handler based on the current locale. */
1576 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001577 status = config_get_locale_encoding(config, &config->stdio_encoding);
1578 if (_PyStatus_EXCEPTION(status)) {
1579 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001580 }
1581 }
1582 if (config->stdio_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001583 const wchar_t *errors = config_get_stdio_errors(config);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001584 assert(errors != NULL);
1585
Victor Stinner331a6a52019-05-27 16:39:22 +02001586 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1587 if (_PyStatus_EXCEPTION(status)) {
1588 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001589 }
1590 }
1591
Victor Stinner331a6a52019-05-27 16:39:22 +02001592 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001593}
1594
1595
Victor Stinner331a6a52019-05-27 16:39:22 +02001596static PyStatus
1597config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001598{
Victor Stinner331a6a52019-05-27 16:39:22 +02001599 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001600
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001601 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001602#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001603 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001604#else
Victor Stinnere2510952019-05-02 11:28:57 -04001605
1606#ifdef MS_WINDOWS
1607 if (preconfig->legacy_windows_fs_encoding) {
1608 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001609 status = PyConfig_SetString(config, &config->filesystem_encoding,
1610 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001611 }
1612 else
1613#endif
Victor Stinner20004952019-03-26 02:31:11 +01001614 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001615 status = PyConfig_SetString(config, &config->filesystem_encoding,
1616 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001617 }
Victor Stinnere2510952019-05-02 11:28:57 -04001618#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001619 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001620 status = PyConfig_SetString(config, &config->filesystem_encoding,
1621 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001622 }
Victor Stinnere2510952019-05-02 11:28:57 -04001623#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001624 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001625#ifdef MS_WINDOWS
1626 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001627 status = PyConfig_SetString(config, &config->filesystem_encoding,
1628 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001629#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001630 status = config_get_locale_encoding(config,
1631 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001632#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001633 }
Victor Stinnere2510952019-05-02 11:28:57 -04001634#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001635
Victor Stinner331a6a52019-05-27 16:39:22 +02001636 if (_PyStatus_EXCEPTION(status)) {
1637 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001638 }
1639 }
1640
1641 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001642 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001643#ifdef MS_WINDOWS
1644 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001645 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001646 }
1647 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001648 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001649 }
1650#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001651 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001652#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001653 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1654 if (_PyStatus_EXCEPTION(status)) {
1655 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001656 }
1657 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001658 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001659}
1660
1661
Victor Stinner331a6a52019-05-27 16:39:22 +02001662static PyStatus
1663config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001664{
Victor Stinner331a6a52019-05-27 16:39:22 +02001665 PyStatus status;
1666 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001667
Victor Stinner20004952019-03-26 02:31:11 +01001668 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001669 status = config_read_env_vars(config);
1670 if (_PyStatus_EXCEPTION(status)) {
1671 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001672 }
1673 }
1674
1675 /* -X options */
1676 if (config_get_xoption(config, L"showrefcount")) {
1677 config->show_ref_count = 1;
1678 }
1679 if (config_get_xoption(config, L"showalloccount")) {
1680 config->show_alloc_count = 1;
1681 }
1682
Victor Stinner331a6a52019-05-27 16:39:22 +02001683 status = config_read_complex_options(config);
1684 if (_PyStatus_EXCEPTION(status)) {
1685 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001686 }
1687
Victor Stinner6c785c02018-08-01 17:56:14 +02001688 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001689 status = config_init_home(config);
1690 if (_PyStatus_EXCEPTION(status)) {
1691 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001692 }
1693 }
1694
Steve Dower177a41a2018-11-17 20:41:48 -08001695 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001696 status = config_init_executable(config);
1697 if (_PyStatus_EXCEPTION(status)) {
1698 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001699 }
1700 }
1701
Victor Stinner6c785c02018-08-01 17:56:14 +02001702 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001703 status = _PyConfig_InitPathConfig(config);
1704 if (_PyStatus_EXCEPTION(status)) {
1705 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001706 }
1707 }
1708
1709 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001710 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001711 if (config->faulthandler < 0) {
1712 config->faulthandler = 1;
1713 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001714 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001715 if (config->faulthandler < 0) {
1716 config->faulthandler = 0;
1717 }
1718 if (config->tracemalloc < 0) {
1719 config->tracemalloc = 0;
1720 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001721 if (config->use_hash_seed < 0) {
1722 config->use_hash_seed = 0;
1723 config->hash_seed = 0;
1724 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001725
Victor Stinner70fead22018-08-29 13:45:34 +02001726 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001727 status = config_init_fs_encoding(config, preconfig);
1728 if (_PyStatus_EXCEPTION(status)) {
1729 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001730 }
1731 }
1732
Victor Stinner331a6a52019-05-27 16:39:22 +02001733 status = config_init_stdio_encoding(config, preconfig);
1734 if (_PyStatus_EXCEPTION(status)) {
1735 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001736 }
1737
Victor Stinner62599762019-03-15 16:03:23 +01001738 if (config->argv.length < 1) {
1739 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001740 status = PyWideStringList_Append(&config->argv, L"");
1741 if (_PyStatus_EXCEPTION(status)) {
1742 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001743 }
1744 }
Victor Stinner870b0352019-05-17 03:15:12 +02001745
1746 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001747 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1748 L"default");
1749 if (_PyStatus_EXCEPTION(status)) {
1750 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001751 }
1752 }
1753
1754 if (config->configure_c_stdio < 0) {
1755 config->configure_c_stdio = 1;
1756 }
1757
Victor Stinner331a6a52019-05-27 16:39:22 +02001758 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001759}
Victor Stinner5ed69952018-11-06 15:59:52 +01001760
1761
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001762static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001763config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001764{
1765#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1766 /* don't translate newlines (\r\n <=> \n) */
1767 _setmode(fileno(stdin), O_BINARY);
1768 _setmode(fileno(stdout), O_BINARY);
1769 _setmode(fileno(stderr), O_BINARY);
1770#endif
1771
1772 if (!config->buffered_stdio) {
1773#ifdef HAVE_SETVBUF
1774 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1775 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1776 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1777#else /* !HAVE_SETVBUF */
1778 setbuf(stdin, (char *)NULL);
1779 setbuf(stdout, (char *)NULL);
1780 setbuf(stderr, (char *)NULL);
1781#endif /* !HAVE_SETVBUF */
1782 }
1783 else if (config->interactive) {
1784#ifdef MS_WINDOWS
1785 /* Doesn't have to have line-buffered -- use unbuffered */
1786 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1787 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1788#else /* !MS_WINDOWS */
1789#ifdef HAVE_SETVBUF
1790 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1791 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1792#endif /* HAVE_SETVBUF */
1793#endif /* !MS_WINDOWS */
1794 /* Leave stderr alone - it should be unbuffered anyway. */
1795 }
1796}
1797
1798
1799/* Write the configuration:
1800
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001801 - set Py_xxx global configuration variables
1802 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001803void
Victor Stinner331a6a52019-05-27 16:39:22 +02001804_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001805{
Victor Stinner331a6a52019-05-27 16:39:22 +02001806 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001807
1808 if (config->configure_c_stdio) {
1809 config_init_stdio(config);
1810 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001811
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001812 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001813 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001814 preconfig->isolated = config->isolated;
1815 preconfig->use_environment = config->use_environment;
1816 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001817}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001818
1819
Victor Stinner331a6a52019-05-27 16:39:22 +02001820/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001821
1822static void
Victor Stinner2f549082019-03-29 15:13:46 +01001823config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001824{
Victor Stinner2f549082019-03-29 15:13:46 +01001825 FILE *f = error ? stderr : stdout;
1826
1827 fprintf(f, usage_line, program);
1828 if (error)
1829 fprintf(f, "Try `python -h' for more information.\n");
1830 else {
1831 fputs(usage_1, f);
1832 fputs(usage_2, f);
1833 fputs(usage_3, f);
1834 fprintf(f, usage_4, (wint_t)DELIM);
1835 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1836 fputs(usage_6, f);
1837 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001838}
1839
1840
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001841/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001842static PyStatus
1843config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001844 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001845{
Victor Stinner331a6a52019-05-27 16:39:22 +02001846 PyStatus status;
1847 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001848 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001849 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001850
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001851 _PyOS_ResetGetOpt();
1852 do {
1853 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001854 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001855 if (c == EOF) {
1856 break;
1857 }
1858
1859 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001860 if (config->run_command == NULL) {
1861 /* -c is the last option; following arguments
1862 that look like options are left for the
1863 command to interpret. */
1864 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1865 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1866 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001867 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001868 }
1869 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1870 command[len - 2] = '\n';
1871 command[len - 1] = 0;
1872 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001873 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001874 break;
1875 }
1876
1877 if (c == 'm') {
1878 /* -m is the last option; following arguments
1879 that look like options are left for the
1880 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001881 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001882 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1883 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001884 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001885 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001886 }
1887 break;
1888 }
1889
1890 switch (c) {
1891 case 0:
1892 // Handle long option.
1893 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001894 if (wcscmp(_PyOS_optarg, L"always") == 0
1895 || wcscmp(_PyOS_optarg, L"never") == 0
1896 || wcscmp(_PyOS_optarg, L"default") == 0)
1897 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001898 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1899 _PyOS_optarg);
1900 if (_PyStatus_EXCEPTION(status)) {
1901 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001902 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001903 } else {
1904 fprintf(stderr, "--check-hash-based-pycs must be one of "
1905 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001906 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001907 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001908 }
1909 break;
1910
1911 case 'b':
1912 config->bytes_warning++;
1913 break;
1914
1915 case 'd':
1916 config->parser_debug++;
1917 break;
1918
1919 case 'i':
1920 config->inspect++;
1921 config->interactive++;
1922 break;
1923
Victor Stinner6dcb5422019-03-05 02:44:12 +01001924 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001925 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001926 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001927 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001928 break;
1929
1930 /* case 'J': reserved for Jython */
1931
1932 case 'O':
1933 config->optimization_level++;
1934 break;
1935
1936 case 'B':
1937 config->write_bytecode = 0;
1938 break;
1939
1940 case 's':
1941 config->user_site_directory = 0;
1942 break;
1943
1944 case 'S':
1945 config->site_import = 0;
1946 break;
1947
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001948 case 't':
1949 /* ignored for backwards compatibility */
1950 break;
1951
1952 case 'u':
1953 config->buffered_stdio = 0;
1954 break;
1955
1956 case 'v':
1957 config->verbose++;
1958 break;
1959
1960 case 'x':
1961 config->skip_source_first_line = 1;
1962 break;
1963
1964 case 'h':
1965 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001966 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001967 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001968
1969 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01001970 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001971 break;
1972
1973 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02001974 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
1975 if (_PyStatus_EXCEPTION(status)) {
1976 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001977 }
1978 break;
1979
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001980 case 'q':
1981 config->quiet++;
1982 break;
1983
1984 case 'R':
1985 config->use_hash_seed = 0;
1986 break;
1987
1988 /* This space reserved for other options */
1989
1990 default:
1991 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02001992 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001993 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001994 }
1995 } while (1);
1996
Victor Stinner2f549082019-03-29 15:13:46 +01001997 if (print_version) {
1998 printf("Python %s\n",
1999 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002000 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002001 }
2002
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002003 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002004 && _PyOS_optind < argv->length
2005 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002006 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002007 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002008 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002009 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002010 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002011 }
2012 }
2013
2014 if (config->run_command != NULL || config->run_module != NULL) {
2015 /* Backup _PyOS_optind */
2016 _PyOS_optind--;
2017 }
2018
Victor Stinnerae239f62019-05-16 17:02:56 +02002019 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002020
Victor Stinner331a6a52019-05-27 16:39:22 +02002021 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002022}
2023
2024
2025#ifdef MS_WINDOWS
2026# define WCSTOK wcstok_s
2027#else
2028# define WCSTOK wcstok
2029#endif
2030
2031/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002032static PyStatus
2033config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002034{
Victor Stinner331a6a52019-05-27 16:39:22 +02002035 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002036 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2037 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002038 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002039 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002040 if (_PyStatus_EXCEPTION(status)) {
2041 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002042 }
2043
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002044 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002045 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002046 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002047 }
2048
2049
2050 wchar_t *warning, *context = NULL;
2051 for (warning = WCSTOK(env, L",", &context);
2052 warning != NULL;
2053 warning = WCSTOK(NULL, L",", &context))
2054 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002055 status = PyWideStringList_Append(warnoptions, warning);
2056 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002057 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002058 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002059 }
2060 }
2061 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002062 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002063}
2064
2065
Victor Stinner331a6a52019-05-27 16:39:22 +02002066static PyStatus
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002067warnoptions_append(PyConfig *config, PyWideStringList *options,
2068 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002069{
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002070 /* config_init_warnoptions() add existing config warnoptions at the end:
2071 ensure that the new option is not already present in this list to
2072 prevent change the options order whne config_init_warnoptions() is
2073 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002074 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002075 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002076 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002077 }
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002078 if (_PyWideStringList_Find(options, option)) {
2079 /* Already present: do nothing */
2080 return _PyStatus_OK();
2081 }
2082 return PyWideStringList_Append(options, option);
2083}
2084
2085
2086static PyStatus
2087warnoptions_extend(PyConfig *config, PyWideStringList *options,
2088 const PyWideStringList *options2)
2089{
2090 const Py_ssize_t len = options2->length;
2091 wchar_t *const *items = options2->items;
2092
2093 for (Py_ssize_t i = 0; i < len; i++) {
2094 PyStatus status = warnoptions_append(config, options, items[i]);
2095 if (_PyStatus_EXCEPTION(status)) {
2096 return status;
2097 }
2098 }
2099 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002100}
2101
2102
Victor Stinner331a6a52019-05-27 16:39:22 +02002103static PyStatus
2104config_init_warnoptions(PyConfig *config,
2105 const PyWideStringList *cmdline_warnoptions,
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002106 const PyWideStringList *env_warnoptions,
2107 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002108{
Victor Stinner331a6a52019-05-27 16:39:22 +02002109 PyStatus status;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002110 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002111
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002112 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002113 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002114 * - any implicit filters added by _warnings.c/warnings.py
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002115 * - PyConfig.dev_mode: "default" filter
2116 * - PYTHONWARNINGS environment variable
2117 * - '-W' command line options
2118 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2119 * "default::BytesWarning" or "error::BytesWarning" filter
2120 * - early PySys_AddWarnOption() calls
2121 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002122 *
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002123 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2124 * module works on the basis of "the most recently added filter will be
2125 * checked first", we add the lowest precedence entries first so that later
2126 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002127 */
2128
Victor Stinner20004952019-03-26 02:31:11 +01002129 if (config->dev_mode) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002130 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002131 if (_PyStatus_EXCEPTION(status)) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002132 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002133 }
2134 }
2135
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002136 status = warnoptions_extend(config, &options, env_warnoptions);
2137 if (_PyStatus_EXCEPTION(status)) {
2138 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002139 }
2140
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002141 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2142 if (_PyStatus_EXCEPTION(status)) {
2143 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002144 }
2145
2146 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2147 * don't even try to emit a warning, so we skip setting the filter in that
2148 * case.
2149 */
2150 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002151 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002152 if (config->bytes_warning> 1) {
2153 filter = L"error::BytesWarning";
2154 }
2155 else {
2156 filter = L"default::BytesWarning";
2157 }
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002158 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002159 if (_PyStatus_EXCEPTION(status)) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002160 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002161 }
2162 }
Victor Stinneraf84a882019-08-23 21:16:51 +02002163
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002164 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinneraf84a882019-08-23 21:16:51 +02002165 if (_PyStatus_EXCEPTION(status)) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002166 goto error;
Victor Stinneraf84a882019-08-23 21:16:51 +02002167 }
2168
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002169 /* Always add all PyConfig.warnoptions options */
2170 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2171 if (_PyStatus_EXCEPTION(status)) {
2172 goto error;
2173 }
2174
2175 _PyWideStringList_Clear(&config->warnoptions);
2176 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002177 return _PyStatus_OK();
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002178
2179error:
2180 _PyWideStringList_Clear(&options);
2181 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002182}
2183
2184
Victor Stinner331a6a52019-05-27 16:39:22 +02002185static PyStatus
2186config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002187{
Victor Stinner331a6a52019-05-27 16:39:22 +02002188 const PyWideStringList *cmdline_argv = &config->argv;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002189 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002190
Victor Stinner74f65682019-03-15 15:08:05 +01002191 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002192 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002193 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002194 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2195 if (_PyStatus_EXCEPTION(status)) {
2196 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002197 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002198 }
2199 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002200 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002201 slice.length = cmdline_argv->length - opt_index;
2202 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002203 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2204 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002205 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002206 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002207 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002208
2209 wchar_t *arg0 = NULL;
2210 if (config->run_command != NULL) {
2211 /* Force sys.argv[0] = '-c' */
2212 arg0 = L"-c";
2213 }
2214 else if (config->run_module != NULL) {
2215 /* Force sys.argv[0] = '-m'*/
2216 arg0 = L"-m";
2217 }
2218 if (arg0 != NULL) {
2219 arg0 = _PyMem_RawWcsdup(arg0);
2220 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002221 _PyWideStringList_Clear(&config_argv);
2222 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002223 }
2224
Victor Stinnerfa153762019-03-20 04:25:38 +01002225 PyMem_RawFree(config_argv.items[0]);
2226 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002227 }
2228
Victor Stinner331a6a52019-05-27 16:39:22 +02002229 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002230 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002231 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002232}
2233
2234
Victor Stinner331a6a52019-05-27 16:39:22 +02002235static PyStatus
2236core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002237{
Victor Stinner331a6a52019-05-27 16:39:22 +02002238 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002239
Victor Stinnercab5d072019-05-17 19:01:14 +02002240 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002241 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2242 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002243 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002244 }
2245
Victor Stinner331a6a52019-05-27 16:39:22 +02002246 PyPreConfig preconfig;
Victor Stinner6e128382019-09-28 04:50:43 +02002247
2248 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2249 if (_PyStatus_EXCEPTION(status)) {
2250 return status;
2251 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002252
Victor Stinner331a6a52019-05-27 16:39:22 +02002253 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002254
Victor Stinner331a6a52019-05-27 16:39:22 +02002255 status = _PyPreCmdline_Read(precmdline, &preconfig);
2256 if (_PyStatus_EXCEPTION(status)) {
2257 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002258 }
2259
Victor Stinner331a6a52019-05-27 16:39:22 +02002260 status = _PyPreCmdline_SetConfig(precmdline, config);
2261 if (_PyStatus_EXCEPTION(status)) {
2262 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002263 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002264 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002265}
2266
2267
Victor Stinner331a6a52019-05-27 16:39:22 +02002268static PyStatus
2269config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002270{
Victor Stinner331a6a52019-05-27 16:39:22 +02002271 PyStatus status;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002272 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2273 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2274 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002275
Victor Stinnerae239f62019-05-16 17:02:56 +02002276 if (config->parse_argv < 0) {
2277 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002278 }
Victor Stinner870b0352019-05-17 03:15:12 +02002279
Victor Stinnerfed02e12019-05-17 11:12:09 +02002280 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002281 status = config_init_program_name(config);
2282 if (_PyStatus_EXCEPTION(status)) {
2283 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002284 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002285 }
Victor Stinner2f549082019-03-29 15:13:46 +01002286
Victor Stinnerae239f62019-05-16 17:02:56 +02002287 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002288 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002289 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2290 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002291 goto done;
2292 }
2293
Victor Stinner331a6a52019-05-27 16:39:22 +02002294 status = config_update_argv(config, opt_index);
2295 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002296 goto done;
2297 }
Victor Stinner2f549082019-03-29 15:13:46 +01002298 }
2299
Victor Stinner2f549082019-03-29 15:13:46 +01002300 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002301 status = config_init_env_warnoptions(config, &env_warnoptions);
2302 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002303 goto done;
2304 }
2305 }
2306
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002307 /* Handle early PySys_AddWarnOption() calls */
2308 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2309 if (_PyStatus_EXCEPTION(status)) {
2310 goto done;
2311 }
2312
Victor Stinner331a6a52019-05-27 16:39:22 +02002313 status = config_init_warnoptions(config,
Victor Stinneraf84a882019-08-23 21:16:51 +02002314 &cmdline_warnoptions,
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002315 &env_warnoptions,
2316 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002317 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002318 goto done;
2319 }
2320
Victor Stinner331a6a52019-05-27 16:39:22 +02002321 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002322
2323done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002324 _PyWideStringList_Clear(&cmdline_warnoptions);
2325 _PyWideStringList_Clear(&env_warnoptions);
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002326 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002327 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002328}
2329
2330
Victor Stinner331a6a52019-05-27 16:39:22 +02002331PyStatus
2332_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002333{
Victor Stinner331a6a52019-05-27 16:39:22 +02002334 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2335 if (_PyStatus_EXCEPTION(status)) {
2336 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002337 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002338
Victor Stinner5f38b842019-05-01 02:30:12 +02002339 return _PyArgv_AsWstrList(args, &config->argv);
2340}
2341
2342
Victor Stinner70005ac2019-05-02 15:25:34 -04002343/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2344 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002345PyStatus
2346PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002347{
2348 _PyArgv args = {
2349 .argc = argc,
2350 .use_bytes_argv = 1,
2351 .bytes_argv = argv,
2352 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002353 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002354}
2355
2356
Victor Stinner331a6a52019-05-27 16:39:22 +02002357PyStatus
2358PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002359{
2360 _PyArgv args = {
2361 .argc = argc,
2362 .use_bytes_argv = 0,
2363 .bytes_argv = NULL,
2364 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002365 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002366}
2367
2368
Miss Islington (bot)96f581c2019-07-01 10:39:58 -07002369PyStatus
2370PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2371 Py_ssize_t length, wchar_t **items)
2372{
2373 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2374 if (_PyStatus_EXCEPTION(status)) {
2375 return status;
2376 }
2377
2378 PyWideStringList list2 = {.length = length, .items = items};
2379 if (_PyWideStringList_Copy(list, &list2) < 0) {
2380 return _PyStatus_NO_MEMORY();
2381 }
2382 return _PyStatus_OK();
2383}
2384
2385
Victor Stinner331a6a52019-05-27 16:39:22 +02002386/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002387
2388 * Command line arguments
2389 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002390 * Py_xxx global configuration variables
2391
2392 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002393PyStatus
2394PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002395{
Victor Stinner331a6a52019-05-27 16:39:22 +02002396 PyStatus status;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002397 PyWideStringList orig_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002398
Victor Stinner331a6a52019-05-27 16:39:22 +02002399 status = _Py_PreInitializeFromConfig(config, NULL);
2400 if (_PyStatus_EXCEPTION(status)) {
2401 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002402 }
2403
Victor Stinner331a6a52019-05-27 16:39:22 +02002404 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002405
Victor Stinner331a6a52019-05-27 16:39:22 +02002406 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2407 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002408 }
2409
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002410 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002411 status = core_read_precmdline(config, &precmdline);
2412 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002413 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002414 }
2415
Victor Stinner870b0352019-05-17 03:15:12 +02002416 assert(config->isolated >= 0);
2417 if (config->isolated) {
2418 config->use_environment = 0;
2419 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002420 }
2421
Victor Stinner331a6a52019-05-27 16:39:22 +02002422 status = config_read_cmdline(config);
2423 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002424 goto done;
2425 }
2426
Victor Stinneraf84a882019-08-23 21:16:51 +02002427 /* Handle early PySys_AddXOption() calls */
2428 status = _PySys_ReadPreinitXOptions(config);
2429 if (_PyStatus_EXCEPTION(status)) {
2430 goto done;
2431 }
2432
Victor Stinner331a6a52019-05-27 16:39:22 +02002433 status = config_read(config);
2434 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002435 goto done;
2436 }
2437
Victor Stinnercab5d072019-05-17 19:01:14 +02002438 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002439 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002440 goto done;
2441 }
2442
2443 /* Check config consistency */
2444 assert(config->isolated >= 0);
2445 assert(config->use_environment >= 0);
2446 assert(config->dev_mode >= 0);
2447 assert(config->install_signal_handlers >= 0);
2448 assert(config->use_hash_seed >= 0);
2449 assert(config->faulthandler >= 0);
2450 assert(config->tracemalloc >= 0);
2451 assert(config->site_import >= 0);
2452 assert(config->bytes_warning >= 0);
2453 assert(config->inspect >= 0);
2454 assert(config->interactive >= 0);
2455 assert(config->optimization_level >= 0);
2456 assert(config->parser_debug >= 0);
2457 assert(config->write_bytecode >= 0);
2458 assert(config->verbose >= 0);
2459 assert(config->quiet >= 0);
2460 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002461 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002462 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002463 assert(config->buffered_stdio >= 0);
2464 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002465 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002466 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2467 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002468 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2469 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2470 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002471 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002472 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002473 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002474 assert(config->executable != NULL);
Steve Dower323e7432019-06-29 14:28:59 -07002475 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002476 assert(config->prefix != NULL);
2477 assert(config->base_prefix != NULL);
2478 assert(config->exec_prefix != NULL);
2479 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002480 }
2481 assert(config->filesystem_encoding != NULL);
2482 assert(config->filesystem_errors != NULL);
2483 assert(config->stdio_encoding != NULL);
2484 assert(config->stdio_errors != NULL);
2485#ifdef MS_WINDOWS
2486 assert(config->legacy_windows_stdio >= 0);
2487#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002488 /* -c and -m options are exclusive */
2489 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002490 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002491 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002492 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002493
Victor Stinner331a6a52019-05-27 16:39:22 +02002494 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002495
2496done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002497 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002498 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002499 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002500}
Victor Stinner1075d162019-03-25 23:19:57 +01002501
2502
2503PyObject*
2504_Py_GetConfigsAsDict(void)
2505{
Victor Stinner331a6a52019-05-27 16:39:22 +02002506 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002507 PyObject *dict = NULL;
2508
Victor Stinner331a6a52019-05-27 16:39:22 +02002509 result = PyDict_New();
2510 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002511 goto error;
2512 }
2513
Victor Stinner331a6a52019-05-27 16:39:22 +02002514 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002515 dict = _Py_GetGlobalVariablesAsDict();
2516 if (dict == NULL) {
2517 goto error;
2518 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002519 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002520 goto error;
2521 }
2522 Py_CLEAR(dict);
2523
2524 /* pre config */
2525 PyInterpreterState *interp = _PyInterpreterState_Get();
Victor Stinner331a6a52019-05-27 16:39:22 +02002526 const PyPreConfig *pre_config = &_PyRuntime.preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002527 dict = _PyPreConfig_AsDict(pre_config);
2528 if (dict == NULL) {
2529 goto error;
2530 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002531 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002532 goto error;
2533 }
2534 Py_CLEAR(dict);
2535
2536 /* core config */
Victor Stinner331a6a52019-05-27 16:39:22 +02002537 const PyConfig *config = &interp->config;
2538 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002539 if (dict == NULL) {
2540 goto error;
2541 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002542 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002543 goto error;
2544 }
2545 Py_CLEAR(dict);
2546
Victor Stinner331a6a52019-05-27 16:39:22 +02002547 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002548
2549error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002550 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002551 Py_XDECREF(dict);
2552 return NULL;
2553}
Victor Stinnerc5c64252019-09-23 15:59:00 +02002554
2555
2556static void
2557init_dump_ascii_wstr(const wchar_t *str)
2558{
2559 if (str == NULL) {
2560 PySys_WriteStderr("(not set)");
2561 return;
2562 }
2563
2564 PySys_WriteStderr("'");
2565 for (; *str != L'\0'; str++) {
2566 wchar_t ch = *str;
2567 if (ch == L'\'') {
2568 PySys_WriteStderr("\\'");
2569 } else if (0x20 <= ch && ch < 0x7f) {
2570 PySys_WriteStderr("%lc", ch);
2571 }
2572 else if (ch <= 0xff) {
2573 PySys_WriteStderr("\\x%02x", ch);
2574 }
2575#if SIZEOF_WCHAR_T > 2
2576 else if (ch > 0xffff) {
2577 PySys_WriteStderr("\\U%08x", ch);
2578 }
2579#endif
2580 else {
2581 PySys_WriteStderr("\\u%04x", ch);
2582 }
2583 }
2584 PySys_WriteStderr("'");
2585}
2586
2587
2588/* Dump the Python path configuration into sys.stderr */
2589void
2590_Py_DumpPathConfig(PyThreadState *tstate)
2591{
2592 PyObject *exc_type, *exc_value, *exc_tb;
2593 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2594
2595 PySys_WriteStderr("Python path configuration:\n");
2596
2597#define DUMP_CONFIG(NAME, FIELD) \
2598 do { \
2599 PySys_WriteStderr(" " NAME " = "); \
2600 init_dump_ascii_wstr(config->FIELD); \
2601 PySys_WriteStderr("\n"); \
2602 } while (0)
2603
2604 PyConfig *config = &tstate->interp->config;
2605 DUMP_CONFIG("PYTHONHOME", home);
2606 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2607 DUMP_CONFIG("program name", program_name);
2608 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2609 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2610 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2611 PySys_WriteStderr(" import site = %i\n", config->site_import);
2612#undef DUMP_CONFIG
2613
2614#define DUMP_SYS(NAME) \
2615 do { \
2616 obj = PySys_GetObject(#NAME); \
2617 PySys_FormatStderr(" sys.%s = ", #NAME); \
2618 if (obj != NULL) { \
2619 PySys_FormatStderr("%A", obj); \
2620 } \
2621 else { \
2622 PySys_WriteStderr("(not set)"); \
2623 } \
2624 PySys_FormatStderr("\n"); \
2625 } while (0)
2626
2627 PyObject *obj;
2628 DUMP_SYS(_base_executable);
2629 DUMP_SYS(base_prefix);
2630 DUMP_SYS(base_exec_prefix);
2631 DUMP_SYS(executable);
2632 DUMP_SYS(prefix);
2633 DUMP_SYS(exec_prefix);
2634#undef DUMP_SYS
2635
2636 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2637 if (sys_path != NULL && PyList_Check(sys_path)) {
2638 PySys_WriteStderr(" sys.path = [\n");
2639 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2640 for (Py_ssize_t i=0; i < len; i++) {
2641 PyObject *path = PyList_GET_ITEM(sys_path, i);
2642 PySys_FormatStderr(" %A,\n", path);
2643 }
2644 PySys_WriteStderr(" ]\n");
2645 }
2646
2647 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2648}