blob: fb04b4a2d22b98daaaa1a425bcca86c75a7a5e17 [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
532static PyStatus
533config_check_struct_size(const PyConfig *config)
534{
535 if (config->struct_size != sizeof(PyConfig)) {
536 return _PyStatus_ERR("unsupported PyConfig structure size "
537 "(Python version mismatch?)");
538 }
539 return _PyStatus_OK();
540}
541
542
Victor Stinner6c785c02018-08-01 17:56:14 +0200543/* Free memory allocated in config, but don't clear all attributes */
544void
Victor Stinner331a6a52019-05-27 16:39:22 +0200545PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200546{
547#define CLEAR(ATTR) \
548 do { \
549 PyMem_RawFree(ATTR); \
550 ATTR = NULL; \
551 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200552
553 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200554 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200555 CLEAR(config->home);
556 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200557
Victor Stinner331a6a52019-05-27 16:39:22 +0200558 _PyWideStringList_Clear(&config->argv);
559 _PyWideStringList_Clear(&config->warnoptions);
560 _PyWideStringList_Clear(&config->xoptions);
561 _PyWideStringList_Clear(&config->module_search_paths);
562 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200563
564 CLEAR(config->executable);
Steve Dower323e7432019-06-29 14:28:59 -0700565 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200566 CLEAR(config->prefix);
567 CLEAR(config->base_prefix);
568 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200569 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200570
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200571 CLEAR(config->filesystem_encoding);
572 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200573 CLEAR(config->stdio_encoding);
574 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100575 CLEAR(config->run_command);
576 CLEAR(config->run_module);
577 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400578 CLEAR(config->check_hash_pycs_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200579#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200580}
581
582
Victor Stinner6e128382019-09-28 04:50:43 +0200583PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200584_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200585{
Victor Stinner6e128382019-09-28 04:50:43 +0200586 size_t struct_size = config->struct_size;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200587 memset(config, 0, sizeof(*config));
Victor Stinner6e128382019-09-28 04:50:43 +0200588 config->struct_size = struct_size;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200589
Victor Stinner6e128382019-09-28 04:50:43 +0200590 PyStatus status = config_check_struct_size(config);
591 if (_PyStatus_EXCEPTION(status)) {
592 _PyStatus_UPDATE_FUNC(status);
593 return status;
594 }
595
Victor Stinner022be022019-05-22 23:58:50 +0200596 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200597 config->isolated = -1;
598 config->use_environment = -1;
599 config->dev_mode = -1;
600 config->install_signal_handlers = 1;
601 config->use_hash_seed = -1;
602 config->faulthandler = -1;
603 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200604 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200605 config->parse_argv = 0;
606 config->site_import = -1;
607 config->bytes_warning = -1;
608 config->inspect = -1;
609 config->interactive = -1;
610 config->optimization_level = -1;
611 config->parser_debug= -1;
612 config->write_bytecode = -1;
613 config->verbose = -1;
614 config->quiet = -1;
615 config->user_site_directory = -1;
616 config->configure_c_stdio = 0;
617 config->buffered_stdio = -1;
618 config->_install_importlib = 1;
619 config->check_hash_pycs_mode = NULL;
620 config->pathconfig_warnings = -1;
621 config->_init_main = 1;
622#ifdef MS_WINDOWS
623 config->legacy_windows_stdio = -1;
624#endif
Victor Stinner6e128382019-09-28 04:50:43 +0200625 return _PyStatus_OK();
Victor Stinnerbab0db62019-05-18 03:21:27 +0200626}
627
628
Victor Stinner6e128382019-09-28 04:50:43 +0200629static PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200630config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200631{
Victor Stinner6e128382019-09-28 04:50:43 +0200632 PyStatus status = _PyConfig_InitCompatConfig(config);
633 if (_PyStatus_EXCEPTION(status)) {
634 return status;
635 }
Victor Stinnerbab0db62019-05-18 03:21:27 +0200636
637 config->isolated = 0;
638 config->use_environment = 1;
639 config->site_import = 1;
640 config->bytes_warning = 0;
641 config->inspect = 0;
642 config->interactive = 0;
643 config->optimization_level = 0;
644 config->parser_debug= 0;
645 config->write_bytecode = 1;
646 config->verbose = 0;
647 config->quiet = 0;
648 config->user_site_directory = 1;
649 config->buffered_stdio = 1;
650 config->pathconfig_warnings = 1;
651#ifdef MS_WINDOWS
652 config->legacy_windows_stdio = 0;
653#endif
Victor Stinner6e128382019-09-28 04:50:43 +0200654 return _PyStatus_OK();
Victor Stinnercab5d072019-05-17 19:01:14 +0200655}
656
657
Victor Stinner331a6a52019-05-27 16:39:22 +0200658PyStatus
659PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200660{
Victor Stinner6e128382019-09-28 04:50:43 +0200661 PyStatus status = config_init_defaults(config);
662 if (_PyStatus_EXCEPTION(status)) {
663 _PyStatus_UPDATE_FUNC(status);
664 return status;
665 }
Victor Stinnercab5d072019-05-17 19:01:14 +0200666
Victor Stinner022be022019-05-22 23:58:50 +0200667 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200668 config->configure_c_stdio = 1;
669 config->parse_argv = 1;
670
Victor Stinner331a6a52019-05-27 16:39:22 +0200671 return _PyStatus_OK();
Victor Stinnercab5d072019-05-17 19:01:14 +0200672}
673
674
Victor Stinner331a6a52019-05-27 16:39:22 +0200675PyStatus
676PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200677{
Victor Stinner6e128382019-09-28 04:50:43 +0200678 PyStatus status = config_init_defaults(config);
679 if (_PyStatus_EXCEPTION(status)) {
680 _PyStatus_UPDATE_FUNC(status);
681 return status;
682 }
Victor Stinnercab5d072019-05-17 19:01:14 +0200683
Victor Stinner022be022019-05-22 23:58:50 +0200684 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200685 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200686 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200687 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200688 config->dev_mode = 0;
689 config->install_signal_handlers = 0;
690 config->use_hash_seed = 0;
691 config->faulthandler = 0;
692 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200693 config->pathconfig_warnings = 0;
694#ifdef MS_WINDOWS
695 config->legacy_windows_stdio = 0;
696#endif
697
Victor Stinner331a6a52019-05-27 16:39:22 +0200698 return _PyStatus_OK();
Victor Stinnercab5d072019-05-17 19:01:14 +0200699}
700
701
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200702/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200703PyStatus
704PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200705{
Victor Stinner331a6a52019-05-27 16:39:22 +0200706 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
707 if (_PyStatus_EXCEPTION(status)) {
708 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200709 }
710
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200711 wchar_t *str2;
712 if (str != NULL) {
713 str2 = _PyMem_RawWcsdup(str);
714 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200715 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200716 }
717 }
718 else {
719 str2 = NULL;
720 }
721 PyMem_RawFree(*config_str);
722 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200723 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200724}
725
726
Victor Stinner331a6a52019-05-27 16:39:22 +0200727static PyStatus
728config_set_bytes_string(PyConfig *config, wchar_t **config_str,
729 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200730{
Victor Stinner331a6a52019-05-27 16:39:22 +0200731 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
732 if (_PyStatus_EXCEPTION(status)) {
733 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400734 }
735
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200736 wchar_t *str2;
737 if (str != NULL) {
738 size_t len;
739 str2 = Py_DecodeLocale(str, &len);
740 if (str2 == NULL) {
741 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200742 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200743 }
744 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200745 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200746 }
747 }
748 }
749 else {
750 str2 = NULL;
751 }
752 PyMem_RawFree(*config_str);
753 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200754 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200755}
756
757
Victor Stinner331a6a52019-05-27 16:39:22 +0200758#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
759 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400760
761
Victor Stinner70005ac2019-05-02 15:25:34 -0400762/* Decode str using Py_DecodeLocale() and set the result into *config_str.
763 Pre-initialize Python if needed to ensure that encodings are properly
764 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200765PyStatus
766PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200767 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400768{
Victor Stinner331a6a52019-05-27 16:39:22 +0200769 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400770}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200771
772
Victor Stinner331a6a52019-05-27 16:39:22 +0200773PyStatus
774_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200775{
Victor Stinner331a6a52019-05-27 16:39:22 +0200776 PyStatus status;
Victor Stinner6e128382019-09-28 04:50:43 +0200777
778 status = config_check_struct_size(config);
779 if (_PyStatus_EXCEPTION(status)) {
780 _PyStatus_UPDATE_FUNC(status);
781 return status;
782 }
783
784 status = config_check_struct_size(config2);
785 if (_PyStatus_EXCEPTION(status)) {
786 _PyStatus_UPDATE_FUNC(status);
787 return status;
788 }
789
Victor Stinner331a6a52019-05-27 16:39:22 +0200790 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200791
792#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200793#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200794 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200795 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
796 if (_PyStatus_EXCEPTION(status)) { \
797 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200798 } \
799 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100800#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200801 do { \
Miss Islington (bot)96f581c2019-07-01 10:39:58 -0700802 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200803 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200804 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200805 } while (0)
806
Victor Stinner6d1c4672019-05-20 11:02:00 +0200807 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100808 COPY_ATTR(isolated);
809 COPY_ATTR(use_environment);
810 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200811 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200812 COPY_ATTR(use_hash_seed);
813 COPY_ATTR(hash_seed);
814 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200815 COPY_ATTR(faulthandler);
816 COPY_ATTR(tracemalloc);
817 COPY_ATTR(import_time);
818 COPY_ATTR(show_ref_count);
819 COPY_ATTR(show_alloc_count);
820 COPY_ATTR(dump_refs);
821 COPY_ATTR(malloc_stats);
822
Victor Stinner124b9eb2018-08-29 01:29:06 +0200823 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200824 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200825 COPY_WSTR_ATTR(home);
826 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200827
Victor Stinnerae239f62019-05-16 17:02:56 +0200828 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100829 COPY_WSTRLIST(argv);
830 COPY_WSTRLIST(warnoptions);
831 COPY_WSTRLIST(xoptions);
832 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200833 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200834
Victor Stinner124b9eb2018-08-29 01:29:06 +0200835 COPY_WSTR_ATTR(executable);
Steve Dower323e7432019-06-29 14:28:59 -0700836 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200837 COPY_WSTR_ATTR(prefix);
838 COPY_WSTR_ATTR(base_prefix);
839 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200840 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200841
Victor Stinner6c785c02018-08-01 17:56:14 +0200842 COPY_ATTR(site_import);
843 COPY_ATTR(bytes_warning);
844 COPY_ATTR(inspect);
845 COPY_ATTR(interactive);
846 COPY_ATTR(optimization_level);
847 COPY_ATTR(parser_debug);
848 COPY_ATTR(write_bytecode);
849 COPY_ATTR(verbose);
850 COPY_ATTR(quiet);
851 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200852 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200853 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400854 COPY_WSTR_ATTR(filesystem_encoding);
855 COPY_WSTR_ATTR(filesystem_errors);
856 COPY_WSTR_ATTR(stdio_encoding);
857 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200858#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200859 COPY_ATTR(legacy_windows_stdio);
860#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100861 COPY_ATTR(skip_source_first_line);
862 COPY_WSTR_ATTR(run_command);
863 COPY_WSTR_ATTR(run_module);
864 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400865 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200866 COPY_ATTR(pathconfig_warnings);
867 COPY_ATTR(_init_main);
Victor Stinner6c785c02018-08-01 17:56:14 +0200868
869#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200870#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200871#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200872 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200873}
874
875
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100876static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200877config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100878{
879 PyObject *dict;
880
881 dict = PyDict_New();
882 if (dict == NULL) {
883 return NULL;
884 }
885
886#define SET_ITEM(KEY, EXPR) \
887 do { \
888 PyObject *obj = (EXPR); \
889 if (obj == NULL) { \
890 goto fail; \
891 } \
892 int res = PyDict_SetItemString(dict, (KEY), obj); \
893 Py_DECREF(obj); \
894 if (res < 0) { \
895 goto fail; \
896 } \
897 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100898#define SET_ITEM_INT(ATTR) \
899 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
900#define SET_ITEM_UINT(ATTR) \
901 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100902#define FROM_WSTRING(STR) \
903 ((STR != NULL) ? \
904 PyUnicode_FromWideChar(STR, -1) \
905 : (Py_INCREF(Py_None), Py_None))
906#define SET_ITEM_WSTR(ATTR) \
907 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
908#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200909 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100910
Victor Stinner6d1c4672019-05-20 11:02:00 +0200911 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100912 SET_ITEM_INT(isolated);
913 SET_ITEM_INT(use_environment);
914 SET_ITEM_INT(dev_mode);
915 SET_ITEM_INT(install_signal_handlers);
916 SET_ITEM_INT(use_hash_seed);
917 SET_ITEM_UINT(hash_seed);
918 SET_ITEM_INT(faulthandler);
919 SET_ITEM_INT(tracemalloc);
920 SET_ITEM_INT(import_time);
921 SET_ITEM_INT(show_ref_count);
922 SET_ITEM_INT(show_alloc_count);
923 SET_ITEM_INT(dump_refs);
924 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400925 SET_ITEM_WSTR(filesystem_encoding);
926 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100927 SET_ITEM_WSTR(pycache_prefix);
928 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200929 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100930 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100931 SET_ITEM_WSTRLIST(xoptions);
932 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200933 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100934 SET_ITEM_WSTR(home);
935 SET_ITEM_WSTRLIST(module_search_paths);
936 SET_ITEM_WSTR(executable);
Steve Dower323e7432019-06-29 14:28:59 -0700937 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100938 SET_ITEM_WSTR(prefix);
939 SET_ITEM_WSTR(base_prefix);
940 SET_ITEM_WSTR(exec_prefix);
941 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100942 SET_ITEM_INT(site_import);
943 SET_ITEM_INT(bytes_warning);
944 SET_ITEM_INT(inspect);
945 SET_ITEM_INT(interactive);
946 SET_ITEM_INT(optimization_level);
947 SET_ITEM_INT(parser_debug);
948 SET_ITEM_INT(write_bytecode);
949 SET_ITEM_INT(verbose);
950 SET_ITEM_INT(quiet);
951 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200952 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100953 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400954 SET_ITEM_WSTR(stdio_encoding);
955 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100956#ifdef MS_WINDOWS
957 SET_ITEM_INT(legacy_windows_stdio);
958#endif
959 SET_ITEM_INT(skip_source_first_line);
960 SET_ITEM_WSTR(run_command);
961 SET_ITEM_WSTR(run_module);
962 SET_ITEM_WSTR(run_filename);
963 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400964 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200965 SET_ITEM_INT(pathconfig_warnings);
966 SET_ITEM_INT(_init_main);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100967
968 return dict;
969
970fail:
971 Py_DECREF(dict);
972 return NULL;
973
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100974#undef FROM_WSTRING
975#undef SET_ITEM
976#undef SET_ITEM_INT
977#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100978#undef SET_ITEM_WSTR
979#undef SET_ITEM_WSTRLIST
980}
981
982
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100983static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200984config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200985{
Victor Stinner20004952019-03-26 02:31:11 +0100986 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200987}
988
989
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100990/* Get a copy of the environment variable as wchar_t*.
991 Return 0 on success, but *dest can be NULL.
992 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200993static PyStatus
994config_get_env_dup(PyConfig *config,
995 wchar_t **dest,
996 wchar_t *wname, char *name,
997 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200998{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200999 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +01001000 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +02001001
Victor Stinner20004952019-03-26 02:31:11 +01001002 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001003 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001004 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001005 }
1006
1007#ifdef MS_WINDOWS
1008 const wchar_t *var = _wgetenv(wname);
1009 if (!var || var[0] == '\0') {
1010 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001011 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001012 }
1013
Victor Stinner331a6a52019-05-27 16:39:22 +02001014 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +02001015#else
1016 const char *var = getenv(name);
1017 if (!var || var[0] == '\0') {
1018 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001019 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001020 }
1021
Victor Stinner331a6a52019-05-27 16:39:22 +02001022 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001023#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001024}
1025
1026
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001027#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001028 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001029
1030
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001031static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001032config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001033{
Victor Stinner022be022019-05-22 23:58:50 +02001034 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1035 /* Python and Isolated configuration ignore global variables */
1036 return;
1037 }
1038
Victor Stinner6c785c02018-08-01 17:56:14 +02001039#define COPY_FLAG(ATTR, VALUE) \
1040 if (config->ATTR == -1) { \
1041 config->ATTR = VALUE; \
1042 }
1043#define COPY_NOT_FLAG(ATTR, VALUE) \
1044 if (config->ATTR == -1) { \
1045 config->ATTR = !(VALUE); \
1046 }
1047
Victor Stinner20004952019-03-26 02:31:11 +01001048 COPY_FLAG(isolated, Py_IsolatedFlag);
1049 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001050 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1051 COPY_FLAG(inspect, Py_InspectFlag);
1052 COPY_FLAG(interactive, Py_InteractiveFlag);
1053 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1054 COPY_FLAG(parser_debug, Py_DebugFlag);
1055 COPY_FLAG(verbose, Py_VerboseFlag);
1056 COPY_FLAG(quiet, Py_QuietFlag);
1057#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001058 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1059#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001060 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001061
Victor Stinner6c785c02018-08-01 17:56:14 +02001062 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1063 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1064 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1065 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1066
Victor Stinner6c785c02018-08-01 17:56:14 +02001067#undef COPY_FLAG
1068#undef COPY_NOT_FLAG
1069}
1070
1071
1072/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001073static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001074config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001075{
1076#define COPY_FLAG(ATTR, VAR) \
1077 if (config->ATTR != -1) { \
1078 VAR = config->ATTR; \
1079 }
1080#define COPY_NOT_FLAG(ATTR, VAR) \
1081 if (config->ATTR != -1) { \
1082 VAR = !config->ATTR; \
1083 }
1084
Victor Stinner20004952019-03-26 02:31:11 +01001085 COPY_FLAG(isolated, Py_IsolatedFlag);
1086 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001087 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1088 COPY_FLAG(inspect, Py_InspectFlag);
1089 COPY_FLAG(interactive, Py_InteractiveFlag);
1090 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1091 COPY_FLAG(parser_debug, Py_DebugFlag);
1092 COPY_FLAG(verbose, Py_VerboseFlag);
1093 COPY_FLAG(quiet, Py_QuietFlag);
1094#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001095 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1096#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001097 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001098
Victor Stinner6c785c02018-08-01 17:56:14 +02001099 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1100 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1101 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1102 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1103
Victor Stinner6c785c02018-08-01 17:56:14 +02001104 /* Random or non-zero hash seed */
1105 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1106 config->hash_seed != 0);
1107
1108#undef COPY_FLAG
1109#undef COPY_NOT_FLAG
1110}
1111
1112
1113/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1114 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001115static PyStatus
1116config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001117{
Victor Stinner331a6a52019-05-27 16:39:22 +02001118 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001119
Victor Stinner6c785c02018-08-01 17:56:14 +02001120 /* If Py_SetProgramName() was called, use its value */
1121 const wchar_t *program_name = _Py_path_config.program_name;
1122 if (program_name != NULL) {
1123 config->program_name = _PyMem_RawWcsdup(program_name);
1124 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001125 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001126 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001127 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001128 }
1129
1130#ifdef __APPLE__
1131 /* On MacOS X, when the Python interpreter is embedded in an
1132 application bundle, it gets executed by a bootstrapping script
1133 that does os.execve() with an argv[0] that's different from the
1134 actual Python executable. This is needed to keep the Finder happy,
1135 or rather, to work around Apple's overly strict requirements of
1136 the process name. However, we still need a usable sys.executable,
1137 so the actual executable path is passed in an environment variable.
1138 See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
1139 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001140 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001141 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001142 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1143 "PYTHONEXECUTABLE environment variable");
1144 if (_PyStatus_EXCEPTION(status)) {
1145 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001146 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001147 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001148 }
1149#ifdef WITH_NEXT_FRAMEWORK
1150 else {
1151 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1152 if (pyvenv_launcher && *pyvenv_launcher) {
1153 /* Used by Mac/Tools/pythonw.c to forward
1154 * the argv0 of the stub executable
1155 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001156 status = CONFIG_SET_BYTES_STR(config,
1157 &config->program_name,
1158 pyvenv_launcher,
1159 "__PYVENV_LAUNCHER__ environment variable");
1160 if (_PyStatus_EXCEPTION(status)) {
1161 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001162 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001163 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001164 }
1165 }
1166#endif /* WITH_NEXT_FRAMEWORK */
1167#endif /* __APPLE__ */
1168
Victor Stinnerfed02e12019-05-17 11:12:09 +02001169 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001170 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001171 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1172 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1173 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001174 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001175 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001176 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001177 }
1178
Victor Stinnerfed02e12019-05-17 11:12:09 +02001179 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001180#ifdef MS_WINDOWS
1181 const wchar_t *default_program_name = L"python";
1182#else
1183 const wchar_t *default_program_name = L"python3";
1184#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001185 status = PyConfig_SetString(config, &config->program_name,
1186 default_program_name);
1187 if (_PyStatus_EXCEPTION(status)) {
1188 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001189 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001190 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001191}
1192
Victor Stinner331a6a52019-05-27 16:39:22 +02001193static PyStatus
1194config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001195{
1196 assert(config->executable == NULL);
1197
1198 /* If Py_SetProgramFullPath() was called, use its value */
1199 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1200 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001201 PyStatus status = PyConfig_SetString(config,
1202 &config->executable,
1203 program_full_path);
1204 if (_PyStatus_EXCEPTION(status)) {
1205 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001206 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001207 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001208 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001209 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001210}
Victor Stinner6c785c02018-08-01 17:56:14 +02001211
Victor Stinner4fffd382019-03-06 01:44:31 +01001212
Victor Stinner6c785c02018-08-01 17:56:14 +02001213static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001214config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001215{
Victor Stinner74f65682019-03-15 15:08:05 +01001216 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001217}
1218
1219
Victor Stinner331a6a52019-05-27 16:39:22 +02001220static PyStatus
1221config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001222{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001223 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001224
1225 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001226 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001227 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001228 PyStatus status = PyConfig_SetString(config, &config->home, home);
1229 if (_PyStatus_EXCEPTION(status)) {
1230 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001231 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001232 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001233 }
1234
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001235 return CONFIG_GET_ENV_DUP(config, &config->home,
1236 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001237}
1238
1239
Victor Stinner331a6a52019-05-27 16:39:22 +02001240static PyStatus
1241config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001242{
Victor Stinner331a6a52019-05-27 16:39:22 +02001243 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001244
1245 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1246 /* Convert a text seed to a numeric one */
1247 if (seed_text && strcmp(seed_text, "random") != 0) {
1248 const char *endptr = seed_text;
1249 unsigned long seed;
1250 errno = 0;
1251 seed = strtoul(seed_text, (char **)&endptr, 10);
1252 if (*endptr != '\0'
1253 || seed > 4294967295UL
1254 || (errno == ERANGE && seed == ULONG_MAX))
1255 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001256 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001257 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001258 }
1259 /* Use a specific hash */
1260 config->use_hash_seed = 1;
1261 config->hash_seed = seed;
1262 }
1263 else {
1264 /* Use a random hash */
1265 config->use_hash_seed = 0;
1266 config->hash_seed = 0;
1267 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001268 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001269}
1270
1271
Victor Stinner6c785c02018-08-01 17:56:14 +02001272static int
1273config_wstr_to_int(const wchar_t *wstr, int *result)
1274{
1275 const wchar_t *endptr = wstr;
1276 errno = 0;
1277 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1278 if (*endptr != '\0' || errno == ERANGE) {
1279 return -1;
1280 }
1281 if (value < INT_MIN || value > INT_MAX) {
1282 return -1;
1283 }
1284
1285 *result = (int)value;
1286 return 0;
1287}
1288
1289
Victor Stinner331a6a52019-05-27 16:39:22 +02001290static PyStatus
1291config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001292{
Victor Stinner331a6a52019-05-27 16:39:22 +02001293 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001294 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001295
Victor Stinner6c785c02018-08-01 17:56:14 +02001296 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001297 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1298 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1299 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1300 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001301
1302 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001303 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001304 if (dont_write_bytecode) {
1305 config->write_bytecode = 0;
1306 }
1307
1308 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001309 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001310 if (no_user_site_directory) {
1311 config->user_site_directory = 0;
1312 }
1313
1314 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001315 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001316 if (unbuffered_stdio) {
1317 config->buffered_stdio = 0;
1318 }
1319
1320#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001321 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001322 "PYTHONLEGACYWINDOWSSTDIO");
1323#endif
1324
Victor Stinner331a6a52019-05-27 16:39:22 +02001325 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001326 config->dump_refs = 1;
1327 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001328 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001329 config->malloc_stats = 1;
1330 }
1331
Victor Stinner331a6a52019-05-27 16:39:22 +02001332 if (config->pythonpath_env == NULL) {
1333 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1334 L"PYTHONPATH", "PYTHONPATH");
1335 if (_PyStatus_EXCEPTION(status)) {
1336 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001337 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001338 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001339
1340 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001341 status = config_init_hash_seed(config);
1342 if (_PyStatus_EXCEPTION(status)) {
1343 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001344 }
1345 }
1346
Victor Stinner331a6a52019-05-27 16:39:22 +02001347 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001348}
1349
1350
Victor Stinner331a6a52019-05-27 16:39:22 +02001351static PyStatus
1352config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001353{
1354 int nframe;
1355 int valid;
1356
Victor Stinner331a6a52019-05-27 16:39:22 +02001357 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001358 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001359 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001360 valid = (nframe >= 0);
1361 }
1362 else {
1363 valid = 0;
1364 }
1365 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001366 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001367 }
1368 config->tracemalloc = nframe;
1369 }
1370
1371 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1372 if (xoption) {
1373 const wchar_t *sep = wcschr(xoption, L'=');
1374 if (sep) {
1375 if (!config_wstr_to_int(sep + 1, &nframe)) {
1376 valid = (nframe >= 0);
1377 }
1378 else {
1379 valid = 0;
1380 }
1381 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001382 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1383 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001384 }
1385 }
1386 else {
1387 /* -X tracemalloc behaves as -X tracemalloc=1 */
1388 nframe = 1;
1389 }
1390 config->tracemalloc = nframe;
1391 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001392 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001393}
1394
1395
Victor Stinner331a6a52019-05-27 16:39:22 +02001396static PyStatus
1397config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001398{
1399 assert(config->pycache_prefix == NULL);
1400
1401 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1402 if (xoption) {
1403 const wchar_t *sep = wcschr(xoption, L'=');
1404 if (sep && wcslen(sep) > 1) {
1405 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1406 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001407 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001408 }
1409 }
1410 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001411 // PYTHONPYCACHEPREFIX env var ignored
1412 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001413 config->pycache_prefix = NULL;
1414 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001415 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001416 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001417
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001418 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1419 L"PYTHONPYCACHEPREFIX",
1420 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001421}
1422
1423
Victor Stinner331a6a52019-05-27 16:39:22 +02001424static PyStatus
1425config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001426{
1427 /* More complex options configured by env var and -X option */
1428 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001429 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001430 || config_get_xoption(config, L"faulthandler")) {
1431 config->faulthandler = 1;
1432 }
1433 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001434 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001435 || config_get_xoption(config, L"importtime")) {
1436 config->import_time = 1;
1437 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001438
Victor Stinner331a6a52019-05-27 16:39:22 +02001439 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001440 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001441 status = config_init_tracemalloc(config);
1442 if (_PyStatus_EXCEPTION(status)) {
1443 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001444 }
1445 }
1446
1447 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001448 status = config_init_pycache_prefix(config);
1449 if (_PyStatus_EXCEPTION(status)) {
1450 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001451 }
1452 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001453 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001454}
1455
1456
Victor Stinner709d23d2019-05-02 14:56:30 -04001457static const wchar_t *
Victor Stinner331a6a52019-05-27 16:39:22 +02001458config_get_stdio_errors(const PyConfig *config)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001459{
1460#ifndef MS_WINDOWS
1461 const char *loc = setlocale(LC_CTYPE, NULL);
1462 if (loc != NULL) {
1463 /* surrogateescape is the default in the legacy C and POSIX locales */
1464 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001465 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001466 }
1467
1468#ifdef PY_COERCE_C_LOCALE
1469 /* surrogateescape is the default in locale coercion target locales */
1470 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001471 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001472 }
1473#endif
1474 }
1475
Victor Stinner709d23d2019-05-02 14:56:30 -04001476 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001477#else
1478 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001479 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001480#endif
1481}
1482
1483
Victor Stinner331a6a52019-05-27 16:39:22 +02001484static PyStatus
1485config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001486{
1487#ifdef MS_WINDOWS
1488 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001489 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001490 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001491#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001492 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001493#else
1494 const char *encoding = nl_langinfo(CODESET);
1495 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001496 return _PyStatus_ERR("failed to get the locale encoding: "
1497 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001498 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001499 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001500 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001501 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001502 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001503#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001504}
1505
1506
Victor Stinner331a6a52019-05-27 16:39:22 +02001507static PyStatus
1508config_init_stdio_encoding(PyConfig *config,
1509 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001510{
Victor Stinner331a6a52019-05-27 16:39:22 +02001511 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001512
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001513 /* If Py_SetStandardStreamEncoding() have been called, use these
1514 parameters. */
1515 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001516 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1517 _Py_StandardStreamEncoding,
1518 "_Py_StandardStreamEncoding");
1519 if (_PyStatus_EXCEPTION(status)) {
1520 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001521 }
1522 }
1523
1524 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001525 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1526 _Py_StandardStreamErrors,
1527 "_Py_StandardStreamErrors");
1528 if (_PyStatus_EXCEPTION(status)) {
1529 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001530 }
1531 }
1532
1533 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001534 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001535 }
1536
1537 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001538 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001539 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001540 char *pythonioencoding = _PyMem_RawStrdup(opt);
1541 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001542 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001543 }
1544
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001545 char *errors = strchr(pythonioencoding, ':');
1546 if (errors) {
1547 *errors = '\0';
1548 errors++;
1549 if (!errors[0]) {
1550 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001551 }
1552 }
1553
1554 /* Does PYTHONIOENCODING contain an encoding? */
1555 if (pythonioencoding[0]) {
1556 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001557 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1558 pythonioencoding,
1559 "PYTHONIOENCODING environment variable");
1560 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001561 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001562 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001563 }
1564 }
1565
1566 /* If the encoding is set but not the error handler,
1567 use "strict" error handler by default.
1568 PYTHONIOENCODING=latin1 behaves as
1569 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001570 if (!errors) {
1571 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001572 }
1573 }
1574
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001575 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001576 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1577 errors,
1578 "PYTHONIOENCODING environment variable");
1579 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001580 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001581 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001582 }
1583 }
1584
1585 PyMem_RawFree(pythonioencoding);
1586 }
1587
1588 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001589 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001590 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001591 status = PyConfig_SetString(config, &config->stdio_encoding,
1592 L"utf-8");
1593 if (_PyStatus_EXCEPTION(status)) {
1594 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001595 }
1596 }
1597 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001598 status = PyConfig_SetString(config, &config->stdio_errors,
1599 L"surrogateescape");
1600 if (_PyStatus_EXCEPTION(status)) {
1601 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001602 }
1603 }
1604 }
1605
1606 /* Choose the default error handler based on the current locale. */
1607 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001608 status = config_get_locale_encoding(config, &config->stdio_encoding);
1609 if (_PyStatus_EXCEPTION(status)) {
1610 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001611 }
1612 }
1613 if (config->stdio_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001614 const wchar_t *errors = config_get_stdio_errors(config);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001615 assert(errors != NULL);
1616
Victor Stinner331a6a52019-05-27 16:39:22 +02001617 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1618 if (_PyStatus_EXCEPTION(status)) {
1619 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001620 }
1621 }
1622
Victor Stinner331a6a52019-05-27 16:39:22 +02001623 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001624}
1625
1626
Victor Stinner331a6a52019-05-27 16:39:22 +02001627static PyStatus
1628config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001629{
Victor Stinner331a6a52019-05-27 16:39:22 +02001630 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001631
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001632 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001633#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001634 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001635#else
Victor Stinnere2510952019-05-02 11:28:57 -04001636
1637#ifdef MS_WINDOWS
1638 if (preconfig->legacy_windows_fs_encoding) {
1639 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001640 status = PyConfig_SetString(config, &config->filesystem_encoding,
1641 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001642 }
1643 else
1644#endif
Victor Stinner20004952019-03-26 02:31:11 +01001645 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001646 status = PyConfig_SetString(config, &config->filesystem_encoding,
1647 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001648 }
Victor Stinnere2510952019-05-02 11:28:57 -04001649#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001650 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001651 status = PyConfig_SetString(config, &config->filesystem_encoding,
1652 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001653 }
Victor Stinnere2510952019-05-02 11:28:57 -04001654#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001655 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001656#ifdef MS_WINDOWS
1657 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001658 status = PyConfig_SetString(config, &config->filesystem_encoding,
1659 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001660#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001661 status = config_get_locale_encoding(config,
1662 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001663#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001664 }
Victor Stinnere2510952019-05-02 11:28:57 -04001665#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001666
Victor Stinner331a6a52019-05-27 16:39:22 +02001667 if (_PyStatus_EXCEPTION(status)) {
1668 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001669 }
1670 }
1671
1672 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001673 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001674#ifdef MS_WINDOWS
1675 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001676 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001677 }
1678 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001679 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001680 }
1681#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001682 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001683#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001684 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1685 if (_PyStatus_EXCEPTION(status)) {
1686 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001687 }
1688 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001689 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001690}
1691
1692
Victor Stinner331a6a52019-05-27 16:39:22 +02001693static PyStatus
1694config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001695{
Victor Stinner331a6a52019-05-27 16:39:22 +02001696 PyStatus status;
1697 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001698
Victor Stinner20004952019-03-26 02:31:11 +01001699 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001700 status = config_read_env_vars(config);
1701 if (_PyStatus_EXCEPTION(status)) {
1702 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001703 }
1704 }
1705
1706 /* -X options */
1707 if (config_get_xoption(config, L"showrefcount")) {
1708 config->show_ref_count = 1;
1709 }
1710 if (config_get_xoption(config, L"showalloccount")) {
1711 config->show_alloc_count = 1;
1712 }
1713
Victor Stinner331a6a52019-05-27 16:39:22 +02001714 status = config_read_complex_options(config);
1715 if (_PyStatus_EXCEPTION(status)) {
1716 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001717 }
1718
Victor Stinner6c785c02018-08-01 17:56:14 +02001719 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001720 status = config_init_home(config);
1721 if (_PyStatus_EXCEPTION(status)) {
1722 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001723 }
1724 }
1725
Steve Dower177a41a2018-11-17 20:41:48 -08001726 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001727 status = config_init_executable(config);
1728 if (_PyStatus_EXCEPTION(status)) {
1729 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001730 }
1731 }
1732
Victor Stinner6c785c02018-08-01 17:56:14 +02001733 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001734 status = _PyConfig_InitPathConfig(config);
1735 if (_PyStatus_EXCEPTION(status)) {
1736 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001737 }
1738 }
1739
1740 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001741 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001742 if (config->faulthandler < 0) {
1743 config->faulthandler = 1;
1744 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001745 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001746 if (config->faulthandler < 0) {
1747 config->faulthandler = 0;
1748 }
1749 if (config->tracemalloc < 0) {
1750 config->tracemalloc = 0;
1751 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001752 if (config->use_hash_seed < 0) {
1753 config->use_hash_seed = 0;
1754 config->hash_seed = 0;
1755 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001756
Victor Stinner70fead22018-08-29 13:45:34 +02001757 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001758 status = config_init_fs_encoding(config, preconfig);
1759 if (_PyStatus_EXCEPTION(status)) {
1760 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001761 }
1762 }
1763
Victor Stinner331a6a52019-05-27 16:39:22 +02001764 status = config_init_stdio_encoding(config, preconfig);
1765 if (_PyStatus_EXCEPTION(status)) {
1766 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001767 }
1768
Victor Stinner62599762019-03-15 16:03:23 +01001769 if (config->argv.length < 1) {
1770 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001771 status = PyWideStringList_Append(&config->argv, L"");
1772 if (_PyStatus_EXCEPTION(status)) {
1773 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001774 }
1775 }
Victor Stinner870b0352019-05-17 03:15:12 +02001776
1777 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001778 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1779 L"default");
1780 if (_PyStatus_EXCEPTION(status)) {
1781 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001782 }
1783 }
1784
1785 if (config->configure_c_stdio < 0) {
1786 config->configure_c_stdio = 1;
1787 }
1788
Victor Stinner331a6a52019-05-27 16:39:22 +02001789 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001790}
Victor Stinner5ed69952018-11-06 15:59:52 +01001791
1792
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001793static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001794config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001795{
1796#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1797 /* don't translate newlines (\r\n <=> \n) */
1798 _setmode(fileno(stdin), O_BINARY);
1799 _setmode(fileno(stdout), O_BINARY);
1800 _setmode(fileno(stderr), O_BINARY);
1801#endif
1802
1803 if (!config->buffered_stdio) {
1804#ifdef HAVE_SETVBUF
1805 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1806 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1807 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1808#else /* !HAVE_SETVBUF */
1809 setbuf(stdin, (char *)NULL);
1810 setbuf(stdout, (char *)NULL);
1811 setbuf(stderr, (char *)NULL);
1812#endif /* !HAVE_SETVBUF */
1813 }
1814 else if (config->interactive) {
1815#ifdef MS_WINDOWS
1816 /* Doesn't have to have line-buffered -- use unbuffered */
1817 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1818 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1819#else /* !MS_WINDOWS */
1820#ifdef HAVE_SETVBUF
1821 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1822 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1823#endif /* HAVE_SETVBUF */
1824#endif /* !MS_WINDOWS */
1825 /* Leave stderr alone - it should be unbuffered anyway. */
1826 }
1827}
1828
1829
1830/* Write the configuration:
1831
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001832 - set Py_xxx global configuration variables
1833 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001834void
Victor Stinner331a6a52019-05-27 16:39:22 +02001835_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001836{
Victor Stinner331a6a52019-05-27 16:39:22 +02001837 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001838
1839 if (config->configure_c_stdio) {
1840 config_init_stdio(config);
1841 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001842
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001843 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001844 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001845 preconfig->isolated = config->isolated;
1846 preconfig->use_environment = config->use_environment;
1847 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001848}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001849
1850
Victor Stinner331a6a52019-05-27 16:39:22 +02001851/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001852
1853static void
Victor Stinner2f549082019-03-29 15:13:46 +01001854config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001855{
Victor Stinner2f549082019-03-29 15:13:46 +01001856 FILE *f = error ? stderr : stdout;
1857
1858 fprintf(f, usage_line, program);
1859 if (error)
1860 fprintf(f, "Try `python -h' for more information.\n");
1861 else {
1862 fputs(usage_1, f);
1863 fputs(usage_2, f);
1864 fputs(usage_3, f);
1865 fprintf(f, usage_4, (wint_t)DELIM);
1866 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1867 fputs(usage_6, f);
1868 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001869}
1870
1871
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001872/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001873static PyStatus
1874config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001875 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001876{
Victor Stinner331a6a52019-05-27 16:39:22 +02001877 PyStatus status;
1878 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001879 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001880 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001881
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001882 _PyOS_ResetGetOpt();
1883 do {
1884 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001885 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001886 if (c == EOF) {
1887 break;
1888 }
1889
1890 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001891 if (config->run_command == NULL) {
1892 /* -c is the last option; following arguments
1893 that look like options are left for the
1894 command to interpret. */
1895 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1896 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1897 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001898 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001899 }
1900 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1901 command[len - 2] = '\n';
1902 command[len - 1] = 0;
1903 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001904 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001905 break;
1906 }
1907
1908 if (c == 'm') {
1909 /* -m is the last option; following arguments
1910 that look like options are left for the
1911 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001912 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001913 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1914 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001915 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001916 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001917 }
1918 break;
1919 }
1920
1921 switch (c) {
1922 case 0:
1923 // Handle long option.
1924 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001925 if (wcscmp(_PyOS_optarg, L"always") == 0
1926 || wcscmp(_PyOS_optarg, L"never") == 0
1927 || wcscmp(_PyOS_optarg, L"default") == 0)
1928 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001929 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1930 _PyOS_optarg);
1931 if (_PyStatus_EXCEPTION(status)) {
1932 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001933 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001934 } else {
1935 fprintf(stderr, "--check-hash-based-pycs must be one of "
1936 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001937 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001938 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001939 }
1940 break;
1941
1942 case 'b':
1943 config->bytes_warning++;
1944 break;
1945
1946 case 'd':
1947 config->parser_debug++;
1948 break;
1949
1950 case 'i':
1951 config->inspect++;
1952 config->interactive++;
1953 break;
1954
Victor Stinner6dcb5422019-03-05 02:44:12 +01001955 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001956 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001957 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001958 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001959 break;
1960
1961 /* case 'J': reserved for Jython */
1962
1963 case 'O':
1964 config->optimization_level++;
1965 break;
1966
1967 case 'B':
1968 config->write_bytecode = 0;
1969 break;
1970
1971 case 's':
1972 config->user_site_directory = 0;
1973 break;
1974
1975 case 'S':
1976 config->site_import = 0;
1977 break;
1978
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001979 case 't':
1980 /* ignored for backwards compatibility */
1981 break;
1982
1983 case 'u':
1984 config->buffered_stdio = 0;
1985 break;
1986
1987 case 'v':
1988 config->verbose++;
1989 break;
1990
1991 case 'x':
1992 config->skip_source_first_line = 1;
1993 break;
1994
1995 case 'h':
1996 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001997 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001998 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001999
2000 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01002001 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002002 break;
2003
2004 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002005 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2006 if (_PyStatus_EXCEPTION(status)) {
2007 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002008 }
2009 break;
2010
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002011 case 'q':
2012 config->quiet++;
2013 break;
2014
2015 case 'R':
2016 config->use_hash_seed = 0;
2017 break;
2018
2019 /* This space reserved for other options */
2020
2021 default:
2022 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002023 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002024 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002025 }
2026 } while (1);
2027
Victor Stinner2f549082019-03-29 15:13:46 +01002028 if (print_version) {
2029 printf("Python %s\n",
2030 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002031 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002032 }
2033
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002034 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002035 && _PyOS_optind < argv->length
2036 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002037 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002038 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002039 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002040 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002041 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002042 }
2043 }
2044
2045 if (config->run_command != NULL || config->run_module != NULL) {
2046 /* Backup _PyOS_optind */
2047 _PyOS_optind--;
2048 }
2049
Victor Stinnerae239f62019-05-16 17:02:56 +02002050 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002051
Victor Stinner331a6a52019-05-27 16:39:22 +02002052 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002053}
2054
2055
2056#ifdef MS_WINDOWS
2057# define WCSTOK wcstok_s
2058#else
2059# define WCSTOK wcstok
2060#endif
2061
2062/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002063static PyStatus
2064config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002065{
Victor Stinner331a6a52019-05-27 16:39:22 +02002066 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002067 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2068 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002069 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002070 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002071 if (_PyStatus_EXCEPTION(status)) {
2072 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002073 }
2074
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002075 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002076 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002077 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002078 }
2079
2080
2081 wchar_t *warning, *context = NULL;
2082 for (warning = WCSTOK(env, L",", &context);
2083 warning != NULL;
2084 warning = WCSTOK(NULL, L",", &context))
2085 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002086 status = PyWideStringList_Append(warnoptions, warning);
2087 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002088 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002089 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002090 }
2091 }
2092 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002093 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002094}
2095
2096
Victor Stinner331a6a52019-05-27 16:39:22 +02002097static PyStatus
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002098warnoptions_append(PyConfig *config, PyWideStringList *options,
2099 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002100{
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002101 /* config_init_warnoptions() add existing config warnoptions at the end:
2102 ensure that the new option is not already present in this list to
2103 prevent change the options order whne config_init_warnoptions() is
2104 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002105 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002106 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002107 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002108 }
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002109 if (_PyWideStringList_Find(options, option)) {
2110 /* Already present: do nothing */
2111 return _PyStatus_OK();
2112 }
2113 return PyWideStringList_Append(options, option);
2114}
2115
2116
2117static PyStatus
2118warnoptions_extend(PyConfig *config, PyWideStringList *options,
2119 const PyWideStringList *options2)
2120{
2121 const Py_ssize_t len = options2->length;
2122 wchar_t *const *items = options2->items;
2123
2124 for (Py_ssize_t i = 0; i < len; i++) {
2125 PyStatus status = warnoptions_append(config, options, items[i]);
2126 if (_PyStatus_EXCEPTION(status)) {
2127 return status;
2128 }
2129 }
2130 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002131}
2132
2133
Victor Stinner331a6a52019-05-27 16:39:22 +02002134static PyStatus
2135config_init_warnoptions(PyConfig *config,
2136 const PyWideStringList *cmdline_warnoptions,
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002137 const PyWideStringList *env_warnoptions,
2138 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002139{
Victor Stinner331a6a52019-05-27 16:39:22 +02002140 PyStatus status;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002141 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002142
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002143 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002144 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002145 * - any implicit filters added by _warnings.c/warnings.py
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002146 * - PyConfig.dev_mode: "default" filter
2147 * - PYTHONWARNINGS environment variable
2148 * - '-W' command line options
2149 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2150 * "default::BytesWarning" or "error::BytesWarning" filter
2151 * - early PySys_AddWarnOption() calls
2152 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002153 *
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002154 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2155 * module works on the basis of "the most recently added filter will be
2156 * checked first", we add the lowest precedence entries first so that later
2157 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002158 */
2159
Victor Stinner20004952019-03-26 02:31:11 +01002160 if (config->dev_mode) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002161 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002162 if (_PyStatus_EXCEPTION(status)) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002163 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002164 }
2165 }
2166
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002167 status = warnoptions_extend(config, &options, env_warnoptions);
2168 if (_PyStatus_EXCEPTION(status)) {
2169 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002170 }
2171
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002172 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2173 if (_PyStatus_EXCEPTION(status)) {
2174 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002175 }
2176
2177 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2178 * don't even try to emit a warning, so we skip setting the filter in that
2179 * case.
2180 */
2181 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002182 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002183 if (config->bytes_warning> 1) {
2184 filter = L"error::BytesWarning";
2185 }
2186 else {
2187 filter = L"default::BytesWarning";
2188 }
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002189 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002190 if (_PyStatus_EXCEPTION(status)) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002191 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002192 }
2193 }
Victor Stinneraf84a882019-08-23 21:16:51 +02002194
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002195 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinneraf84a882019-08-23 21:16:51 +02002196 if (_PyStatus_EXCEPTION(status)) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002197 goto error;
Victor Stinneraf84a882019-08-23 21:16:51 +02002198 }
2199
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002200 /* Always add all PyConfig.warnoptions options */
2201 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2202 if (_PyStatus_EXCEPTION(status)) {
2203 goto error;
2204 }
2205
2206 _PyWideStringList_Clear(&config->warnoptions);
2207 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002208 return _PyStatus_OK();
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002209
2210error:
2211 _PyWideStringList_Clear(&options);
2212 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002213}
2214
2215
Victor Stinner331a6a52019-05-27 16:39:22 +02002216static PyStatus
2217config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002218{
Victor Stinner331a6a52019-05-27 16:39:22 +02002219 const PyWideStringList *cmdline_argv = &config->argv;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002220 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002221
Victor Stinner74f65682019-03-15 15:08:05 +01002222 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002223 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002224 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002225 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2226 if (_PyStatus_EXCEPTION(status)) {
2227 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002228 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002229 }
2230 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002231 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002232 slice.length = cmdline_argv->length - opt_index;
2233 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002234 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2235 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002236 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002237 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002238 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002239
2240 wchar_t *arg0 = NULL;
2241 if (config->run_command != NULL) {
2242 /* Force sys.argv[0] = '-c' */
2243 arg0 = L"-c";
2244 }
2245 else if (config->run_module != NULL) {
2246 /* Force sys.argv[0] = '-m'*/
2247 arg0 = L"-m";
2248 }
2249 if (arg0 != NULL) {
2250 arg0 = _PyMem_RawWcsdup(arg0);
2251 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002252 _PyWideStringList_Clear(&config_argv);
2253 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002254 }
2255
Victor Stinnerfa153762019-03-20 04:25:38 +01002256 PyMem_RawFree(config_argv.items[0]);
2257 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002258 }
2259
Victor Stinner331a6a52019-05-27 16:39:22 +02002260 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002261 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002262 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002263}
2264
2265
Victor Stinner331a6a52019-05-27 16:39:22 +02002266static PyStatus
2267core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002268{
Victor Stinner331a6a52019-05-27 16:39:22 +02002269 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002270
Victor Stinnercab5d072019-05-17 19:01:14 +02002271 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002272 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2273 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002274 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002275 }
2276
Victor Stinner331a6a52019-05-27 16:39:22 +02002277 PyPreConfig preconfig;
Victor Stinner6e128382019-09-28 04:50:43 +02002278 preconfig.struct_size = sizeof(PyPreConfig);
2279
2280 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2281 if (_PyStatus_EXCEPTION(status)) {
2282 return status;
2283 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002284
Victor Stinner331a6a52019-05-27 16:39:22 +02002285 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002286
Victor Stinner331a6a52019-05-27 16:39:22 +02002287 status = _PyPreCmdline_Read(precmdline, &preconfig);
2288 if (_PyStatus_EXCEPTION(status)) {
2289 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002290 }
2291
Victor Stinner331a6a52019-05-27 16:39:22 +02002292 status = _PyPreCmdline_SetConfig(precmdline, config);
2293 if (_PyStatus_EXCEPTION(status)) {
2294 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002295 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002296 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002297}
2298
2299
Victor Stinner331a6a52019-05-27 16:39:22 +02002300static PyStatus
2301config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002302{
Victor Stinner331a6a52019-05-27 16:39:22 +02002303 PyStatus status;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002304 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2305 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2306 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002307
Victor Stinnerae239f62019-05-16 17:02:56 +02002308 if (config->parse_argv < 0) {
2309 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002310 }
Victor Stinner870b0352019-05-17 03:15:12 +02002311
Victor Stinnerfed02e12019-05-17 11:12:09 +02002312 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002313 status = config_init_program_name(config);
2314 if (_PyStatus_EXCEPTION(status)) {
2315 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002316 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002317 }
Victor Stinner2f549082019-03-29 15:13:46 +01002318
Victor Stinnerae239f62019-05-16 17:02:56 +02002319 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002320 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002321 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2322 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002323 goto done;
2324 }
2325
Victor Stinner331a6a52019-05-27 16:39:22 +02002326 status = config_update_argv(config, opt_index);
2327 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002328 goto done;
2329 }
Victor Stinner2f549082019-03-29 15:13:46 +01002330 }
2331
Victor Stinner2f549082019-03-29 15:13:46 +01002332 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002333 status = config_init_env_warnoptions(config, &env_warnoptions);
2334 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002335 goto done;
2336 }
2337 }
2338
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002339 /* Handle early PySys_AddWarnOption() calls */
2340 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2341 if (_PyStatus_EXCEPTION(status)) {
2342 goto done;
2343 }
2344
Victor Stinner331a6a52019-05-27 16:39:22 +02002345 status = config_init_warnoptions(config,
Victor Stinneraf84a882019-08-23 21:16:51 +02002346 &cmdline_warnoptions,
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002347 &env_warnoptions,
2348 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002349 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002350 goto done;
2351 }
2352
Victor Stinner331a6a52019-05-27 16:39:22 +02002353 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002354
2355done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002356 _PyWideStringList_Clear(&cmdline_warnoptions);
2357 _PyWideStringList_Clear(&env_warnoptions);
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002358 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002359 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002360}
2361
2362
Victor Stinner331a6a52019-05-27 16:39:22 +02002363PyStatus
2364_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002365{
Victor Stinner331a6a52019-05-27 16:39:22 +02002366 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2367 if (_PyStatus_EXCEPTION(status)) {
2368 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002369 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002370
Victor Stinner5f38b842019-05-01 02:30:12 +02002371 return _PyArgv_AsWstrList(args, &config->argv);
2372}
2373
2374
Victor Stinner70005ac2019-05-02 15:25:34 -04002375/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2376 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002377PyStatus
2378PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002379{
2380 _PyArgv args = {
2381 .argc = argc,
2382 .use_bytes_argv = 1,
2383 .bytes_argv = argv,
2384 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002385 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002386}
2387
2388
Victor Stinner331a6a52019-05-27 16:39:22 +02002389PyStatus
2390PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002391{
2392 _PyArgv args = {
2393 .argc = argc,
2394 .use_bytes_argv = 0,
2395 .bytes_argv = NULL,
2396 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002397 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002398}
2399
2400
Miss Islington (bot)96f581c2019-07-01 10:39:58 -07002401PyStatus
2402PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2403 Py_ssize_t length, wchar_t **items)
2404{
2405 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2406 if (_PyStatus_EXCEPTION(status)) {
2407 return status;
2408 }
2409
2410 PyWideStringList list2 = {.length = length, .items = items};
2411 if (_PyWideStringList_Copy(list, &list2) < 0) {
2412 return _PyStatus_NO_MEMORY();
2413 }
2414 return _PyStatus_OK();
2415}
2416
2417
Victor Stinner331a6a52019-05-27 16:39:22 +02002418/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002419
2420 * Command line arguments
2421 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002422 * Py_xxx global configuration variables
2423
2424 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002425PyStatus
2426PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002427{
Victor Stinner331a6a52019-05-27 16:39:22 +02002428 PyStatus status;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002429 PyWideStringList orig_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002430
Victor Stinner6e128382019-09-28 04:50:43 +02002431 status = config_check_struct_size(config);
2432 if (_PyStatus_EXCEPTION(status)) {
2433 _PyStatus_UPDATE_FUNC(status);
2434 return status;
2435 }
2436
Victor Stinner331a6a52019-05-27 16:39:22 +02002437 status = _Py_PreInitializeFromConfig(config, NULL);
2438 if (_PyStatus_EXCEPTION(status)) {
2439 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002440 }
2441
Victor Stinner331a6a52019-05-27 16:39:22 +02002442 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002443
Victor Stinner331a6a52019-05-27 16:39:22 +02002444 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2445 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002446 }
2447
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002448 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002449 status = core_read_precmdline(config, &precmdline);
2450 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002451 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002452 }
2453
Victor Stinner870b0352019-05-17 03:15:12 +02002454 assert(config->isolated >= 0);
2455 if (config->isolated) {
2456 config->use_environment = 0;
2457 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002458 }
2459
Victor Stinner331a6a52019-05-27 16:39:22 +02002460 status = config_read_cmdline(config);
2461 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002462 goto done;
2463 }
2464
Victor Stinneraf84a882019-08-23 21:16:51 +02002465 /* Handle early PySys_AddXOption() calls */
2466 status = _PySys_ReadPreinitXOptions(config);
2467 if (_PyStatus_EXCEPTION(status)) {
2468 goto done;
2469 }
2470
Victor Stinner331a6a52019-05-27 16:39:22 +02002471 status = config_read(config);
2472 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002473 goto done;
2474 }
2475
Victor Stinnercab5d072019-05-17 19:01:14 +02002476 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002477 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002478 goto done;
2479 }
2480
2481 /* Check config consistency */
2482 assert(config->isolated >= 0);
2483 assert(config->use_environment >= 0);
2484 assert(config->dev_mode >= 0);
2485 assert(config->install_signal_handlers >= 0);
2486 assert(config->use_hash_seed >= 0);
2487 assert(config->faulthandler >= 0);
2488 assert(config->tracemalloc >= 0);
2489 assert(config->site_import >= 0);
2490 assert(config->bytes_warning >= 0);
2491 assert(config->inspect >= 0);
2492 assert(config->interactive >= 0);
2493 assert(config->optimization_level >= 0);
2494 assert(config->parser_debug >= 0);
2495 assert(config->write_bytecode >= 0);
2496 assert(config->verbose >= 0);
2497 assert(config->quiet >= 0);
2498 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002499 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002500 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002501 assert(config->buffered_stdio >= 0);
2502 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002503 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002504 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2505 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002506 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2507 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2508 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002509 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002510 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002511 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002512 assert(config->executable != NULL);
Steve Dower323e7432019-06-29 14:28:59 -07002513 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002514 assert(config->prefix != NULL);
2515 assert(config->base_prefix != NULL);
2516 assert(config->exec_prefix != NULL);
2517 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002518 }
2519 assert(config->filesystem_encoding != NULL);
2520 assert(config->filesystem_errors != NULL);
2521 assert(config->stdio_encoding != NULL);
2522 assert(config->stdio_errors != NULL);
2523#ifdef MS_WINDOWS
2524 assert(config->legacy_windows_stdio >= 0);
2525#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002526 /* -c and -m options are exclusive */
2527 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002528 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002529 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002530 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002531
Victor Stinner331a6a52019-05-27 16:39:22 +02002532 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002533
2534done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002535 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002536 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002537 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002538}
Victor Stinner1075d162019-03-25 23:19:57 +01002539
2540
2541PyObject*
2542_Py_GetConfigsAsDict(void)
2543{
Victor Stinner331a6a52019-05-27 16:39:22 +02002544 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002545 PyObject *dict = NULL;
2546
Victor Stinner331a6a52019-05-27 16:39:22 +02002547 result = PyDict_New();
2548 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002549 goto error;
2550 }
2551
Victor Stinner331a6a52019-05-27 16:39:22 +02002552 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002553 dict = _Py_GetGlobalVariablesAsDict();
2554 if (dict == NULL) {
2555 goto error;
2556 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002557 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002558 goto error;
2559 }
2560 Py_CLEAR(dict);
2561
2562 /* pre config */
2563 PyInterpreterState *interp = _PyInterpreterState_Get();
Victor Stinner331a6a52019-05-27 16:39:22 +02002564 const PyPreConfig *pre_config = &_PyRuntime.preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002565 dict = _PyPreConfig_AsDict(pre_config);
2566 if (dict == NULL) {
2567 goto error;
2568 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002569 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002570 goto error;
2571 }
2572 Py_CLEAR(dict);
2573
2574 /* core config */
Victor Stinner331a6a52019-05-27 16:39:22 +02002575 const PyConfig *config = &interp->config;
2576 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002577 if (dict == NULL) {
2578 goto error;
2579 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002580 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002581 goto error;
2582 }
2583 Py_CLEAR(dict);
2584
Victor Stinner331a6a52019-05-27 16:39:22 +02002585 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002586
2587error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002588 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002589 Py_XDECREF(dict);
2590 return NULL;
2591}
Victor Stinnerc5c64252019-09-23 15:59:00 +02002592
2593
2594static void
2595init_dump_ascii_wstr(const wchar_t *str)
2596{
2597 if (str == NULL) {
2598 PySys_WriteStderr("(not set)");
2599 return;
2600 }
2601
2602 PySys_WriteStderr("'");
2603 for (; *str != L'\0'; str++) {
2604 wchar_t ch = *str;
2605 if (ch == L'\'') {
2606 PySys_WriteStderr("\\'");
2607 } else if (0x20 <= ch && ch < 0x7f) {
2608 PySys_WriteStderr("%lc", ch);
2609 }
2610 else if (ch <= 0xff) {
2611 PySys_WriteStderr("\\x%02x", ch);
2612 }
2613#if SIZEOF_WCHAR_T > 2
2614 else if (ch > 0xffff) {
2615 PySys_WriteStderr("\\U%08x", ch);
2616 }
2617#endif
2618 else {
2619 PySys_WriteStderr("\\u%04x", ch);
2620 }
2621 }
2622 PySys_WriteStderr("'");
2623}
2624
2625
2626/* Dump the Python path configuration into sys.stderr */
2627void
2628_Py_DumpPathConfig(PyThreadState *tstate)
2629{
2630 PyObject *exc_type, *exc_value, *exc_tb;
2631 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2632
2633 PySys_WriteStderr("Python path configuration:\n");
2634
2635#define DUMP_CONFIG(NAME, FIELD) \
2636 do { \
2637 PySys_WriteStderr(" " NAME " = "); \
2638 init_dump_ascii_wstr(config->FIELD); \
2639 PySys_WriteStderr("\n"); \
2640 } while (0)
2641
2642 PyConfig *config = &tstate->interp->config;
2643 DUMP_CONFIG("PYTHONHOME", home);
2644 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2645 DUMP_CONFIG("program name", program_name);
2646 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2647 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2648 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2649 PySys_WriteStderr(" import site = %i\n", config->site_import);
2650#undef DUMP_CONFIG
2651
2652#define DUMP_SYS(NAME) \
2653 do { \
2654 obj = PySys_GetObject(#NAME); \
2655 PySys_FormatStderr(" sys.%s = ", #NAME); \
2656 if (obj != NULL) { \
2657 PySys_FormatStderr("%A", obj); \
2658 } \
2659 else { \
2660 PySys_WriteStderr("(not set)"); \
2661 } \
2662 PySys_FormatStderr("\n"); \
2663 } while (0)
2664
2665 PyObject *obj;
2666 DUMP_SYS(_base_executable);
2667 DUMP_SYS(base_prefix);
2668 DUMP_SYS(base_exec_prefix);
2669 DUMP_SYS(executable);
2670 DUMP_SYS(prefix);
2671 DUMP_SYS(exec_prefix);
2672#undef DUMP_SYS
2673
2674 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2675 if (sys_path != NULL && PyList_Check(sys_path)) {
2676 PySys_WriteStderr(" sys.path = [\n");
2677 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2678 for (Py_ssize_t i=0; i < len; i++) {
2679 PyObject *path = PyList_GET_ITEM(sys_path, i);
2680 PySys_FormatStderr(" %A,\n", path);
2681 }
2682 PySys_WriteStderr(" ]\n");
2683 }
2684
2685 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2686}