blob: a527271452ea53de93117e2eb11b722a9b2516d8 [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
Victor Stinner331a6a52019-05-27 16:39:22 +0200276 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 Stinner6c785c02018-08-01 17:56:14 +0200531/* Free memory allocated in config, but don't clear all attributes */
532void
Victor Stinner331a6a52019-05-27 16:39:22 +0200533PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200534{
535#define CLEAR(ATTR) \
536 do { \
537 PyMem_RawFree(ATTR); \
538 ATTR = NULL; \
539 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200540
541 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200542 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200543 CLEAR(config->home);
544 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200545
Victor Stinner331a6a52019-05-27 16:39:22 +0200546 _PyWideStringList_Clear(&config->argv);
547 _PyWideStringList_Clear(&config->warnoptions);
548 _PyWideStringList_Clear(&config->xoptions);
549 _PyWideStringList_Clear(&config->module_search_paths);
550 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200551
552 CLEAR(config->executable);
Steve Dower323e7432019-06-29 14:28:59 -0700553 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200554 CLEAR(config->prefix);
555 CLEAR(config->base_prefix);
556 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200557 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200558
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200559 CLEAR(config->filesystem_encoding);
560 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200561 CLEAR(config->stdio_encoding);
562 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100563 CLEAR(config->run_command);
564 CLEAR(config->run_module);
565 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400566 CLEAR(config->check_hash_pycs_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200567#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200568}
569
570
Victor Stinnercab5d072019-05-17 19:01:14 +0200571void
Victor Stinner331a6a52019-05-27 16:39:22 +0200572_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200573{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200574 memset(config, 0, sizeof(*config));
575
576 config->_config_version = _Py_CONFIG_VERSION;
Victor Stinner022be022019-05-22 23:58:50 +0200577 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200578 config->isolated = -1;
579 config->use_environment = -1;
580 config->dev_mode = -1;
581 config->install_signal_handlers = 1;
582 config->use_hash_seed = -1;
583 config->faulthandler = -1;
584 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200585 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200586 config->parse_argv = 0;
587 config->site_import = -1;
588 config->bytes_warning = -1;
589 config->inspect = -1;
590 config->interactive = -1;
591 config->optimization_level = -1;
592 config->parser_debug= -1;
593 config->write_bytecode = -1;
594 config->verbose = -1;
595 config->quiet = -1;
596 config->user_site_directory = -1;
597 config->configure_c_stdio = 0;
598 config->buffered_stdio = -1;
599 config->_install_importlib = 1;
600 config->check_hash_pycs_mode = NULL;
601 config->pathconfig_warnings = -1;
602 config->_init_main = 1;
603#ifdef MS_WINDOWS
604 config->legacy_windows_stdio = -1;
605#endif
606}
607
608
609static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200610config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200611{
Victor Stinner331a6a52019-05-27 16:39:22 +0200612 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200613
614 config->isolated = 0;
615 config->use_environment = 1;
616 config->site_import = 1;
617 config->bytes_warning = 0;
618 config->inspect = 0;
619 config->interactive = 0;
620 config->optimization_level = 0;
621 config->parser_debug= 0;
622 config->write_bytecode = 1;
623 config->verbose = 0;
624 config->quiet = 0;
625 config->user_site_directory = 1;
626 config->buffered_stdio = 1;
627 config->pathconfig_warnings = 1;
628#ifdef MS_WINDOWS
629 config->legacy_windows_stdio = 0;
630#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200631}
632
633
Victor Stinner331a6a52019-05-27 16:39:22 +0200634PyStatus
635PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200636{
Victor Stinner331a6a52019-05-27 16:39:22 +0200637 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200638
Victor Stinner022be022019-05-22 23:58:50 +0200639 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200640 config->configure_c_stdio = 1;
641 config->parse_argv = 1;
642
Victor Stinner331a6a52019-05-27 16:39:22 +0200643 return _PyStatus_OK();
Victor Stinnercab5d072019-05-17 19:01:14 +0200644}
645
646
Victor Stinner331a6a52019-05-27 16:39:22 +0200647PyStatus
648PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200649{
Victor Stinner331a6a52019-05-27 16:39:22 +0200650 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200651
Victor Stinner022be022019-05-22 23:58:50 +0200652 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200653 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200654 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200655 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200656 config->dev_mode = 0;
657 config->install_signal_handlers = 0;
658 config->use_hash_seed = 0;
659 config->faulthandler = 0;
660 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200661 config->pathconfig_warnings = 0;
662#ifdef MS_WINDOWS
663 config->legacy_windows_stdio = 0;
664#endif
665
Victor Stinner331a6a52019-05-27 16:39:22 +0200666 return _PyStatus_OK();
Victor Stinnercab5d072019-05-17 19:01:14 +0200667}
668
669
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200670/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200671PyStatus
672PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200673{
Victor Stinner331a6a52019-05-27 16:39:22 +0200674 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
675 if (_PyStatus_EXCEPTION(status)) {
676 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200677 }
678
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200679 wchar_t *str2;
680 if (str != NULL) {
681 str2 = _PyMem_RawWcsdup(str);
682 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200683 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200684 }
685 }
686 else {
687 str2 = NULL;
688 }
689 PyMem_RawFree(*config_str);
690 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200691 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200692}
693
694
Victor Stinner331a6a52019-05-27 16:39:22 +0200695static PyStatus
696config_set_bytes_string(PyConfig *config, wchar_t **config_str,
697 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200698{
Victor Stinner331a6a52019-05-27 16:39:22 +0200699 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
700 if (_PyStatus_EXCEPTION(status)) {
701 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400702 }
703
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200704 wchar_t *str2;
705 if (str != NULL) {
706 size_t len;
707 str2 = Py_DecodeLocale(str, &len);
708 if (str2 == NULL) {
709 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200710 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200711 }
712 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200713 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200714 }
715 }
716 }
717 else {
718 str2 = NULL;
719 }
720 PyMem_RawFree(*config_str);
721 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200722 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200723}
724
725
Victor Stinner331a6a52019-05-27 16:39:22 +0200726#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
727 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400728
729
Victor Stinner70005ac2019-05-02 15:25:34 -0400730/* Decode str using Py_DecodeLocale() and set the result into *config_str.
731 Pre-initialize Python if needed to ensure that encodings are properly
732 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200733PyStatus
734PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200735 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400736{
Victor Stinner331a6a52019-05-27 16:39:22 +0200737 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400738}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200739
740
Victor Stinner331a6a52019-05-27 16:39:22 +0200741PyStatus
742_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200743{
Victor Stinner331a6a52019-05-27 16:39:22 +0200744 PyStatus status;
745 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200746
747#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200748#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200749 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200750 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
751 if (_PyStatus_EXCEPTION(status)) { \
752 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200753 } \
754 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100755#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200756 do { \
Miss Islington (bot)96f581c2019-07-01 10:39:58 -0700757 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200758 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200759 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200760 } while (0)
761
Victor Stinner6d1c4672019-05-20 11:02:00 +0200762 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100763 COPY_ATTR(isolated);
764 COPY_ATTR(use_environment);
765 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200766 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200767 COPY_ATTR(use_hash_seed);
768 COPY_ATTR(hash_seed);
769 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200770 COPY_ATTR(faulthandler);
771 COPY_ATTR(tracemalloc);
772 COPY_ATTR(import_time);
773 COPY_ATTR(show_ref_count);
774 COPY_ATTR(show_alloc_count);
775 COPY_ATTR(dump_refs);
776 COPY_ATTR(malloc_stats);
777
Victor Stinner124b9eb2018-08-29 01:29:06 +0200778 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200779 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200780 COPY_WSTR_ATTR(home);
781 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200782
Victor Stinnerae239f62019-05-16 17:02:56 +0200783 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100784 COPY_WSTRLIST(argv);
785 COPY_WSTRLIST(warnoptions);
786 COPY_WSTRLIST(xoptions);
787 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200788 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200789
Victor Stinner124b9eb2018-08-29 01:29:06 +0200790 COPY_WSTR_ATTR(executable);
Steve Dower323e7432019-06-29 14:28:59 -0700791 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200792 COPY_WSTR_ATTR(prefix);
793 COPY_WSTR_ATTR(base_prefix);
794 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200795 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200796
Victor Stinner6c785c02018-08-01 17:56:14 +0200797 COPY_ATTR(site_import);
798 COPY_ATTR(bytes_warning);
799 COPY_ATTR(inspect);
800 COPY_ATTR(interactive);
801 COPY_ATTR(optimization_level);
802 COPY_ATTR(parser_debug);
803 COPY_ATTR(write_bytecode);
804 COPY_ATTR(verbose);
805 COPY_ATTR(quiet);
806 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200807 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200808 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400809 COPY_WSTR_ATTR(filesystem_encoding);
810 COPY_WSTR_ATTR(filesystem_errors);
811 COPY_WSTR_ATTR(stdio_encoding);
812 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200813#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200814 COPY_ATTR(legacy_windows_stdio);
815#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100816 COPY_ATTR(skip_source_first_line);
817 COPY_WSTR_ATTR(run_command);
818 COPY_WSTR_ATTR(run_module);
819 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400820 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200821 COPY_ATTR(pathconfig_warnings);
822 COPY_ATTR(_init_main);
Victor Stinner6c785c02018-08-01 17:56:14 +0200823
824#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200825#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200826#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200827 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200828}
829
830
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100831static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200832config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100833{
834 PyObject *dict;
835
836 dict = PyDict_New();
837 if (dict == NULL) {
838 return NULL;
839 }
840
841#define SET_ITEM(KEY, EXPR) \
842 do { \
843 PyObject *obj = (EXPR); \
844 if (obj == NULL) { \
845 goto fail; \
846 } \
847 int res = PyDict_SetItemString(dict, (KEY), obj); \
848 Py_DECREF(obj); \
849 if (res < 0) { \
850 goto fail; \
851 } \
852 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100853#define SET_ITEM_INT(ATTR) \
854 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
855#define SET_ITEM_UINT(ATTR) \
856 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100857#define FROM_WSTRING(STR) \
858 ((STR != NULL) ? \
859 PyUnicode_FromWideChar(STR, -1) \
860 : (Py_INCREF(Py_None), Py_None))
861#define SET_ITEM_WSTR(ATTR) \
862 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
863#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200864 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100865
Victor Stinner6d1c4672019-05-20 11:02:00 +0200866 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100867 SET_ITEM_INT(isolated);
868 SET_ITEM_INT(use_environment);
869 SET_ITEM_INT(dev_mode);
870 SET_ITEM_INT(install_signal_handlers);
871 SET_ITEM_INT(use_hash_seed);
872 SET_ITEM_UINT(hash_seed);
873 SET_ITEM_INT(faulthandler);
874 SET_ITEM_INT(tracemalloc);
875 SET_ITEM_INT(import_time);
876 SET_ITEM_INT(show_ref_count);
877 SET_ITEM_INT(show_alloc_count);
878 SET_ITEM_INT(dump_refs);
879 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400880 SET_ITEM_WSTR(filesystem_encoding);
881 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100882 SET_ITEM_WSTR(pycache_prefix);
883 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200884 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100885 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100886 SET_ITEM_WSTRLIST(xoptions);
887 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200888 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100889 SET_ITEM_WSTR(home);
890 SET_ITEM_WSTRLIST(module_search_paths);
891 SET_ITEM_WSTR(executable);
Steve Dower323e7432019-06-29 14:28:59 -0700892 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100893 SET_ITEM_WSTR(prefix);
894 SET_ITEM_WSTR(base_prefix);
895 SET_ITEM_WSTR(exec_prefix);
896 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100897 SET_ITEM_INT(site_import);
898 SET_ITEM_INT(bytes_warning);
899 SET_ITEM_INT(inspect);
900 SET_ITEM_INT(interactive);
901 SET_ITEM_INT(optimization_level);
902 SET_ITEM_INT(parser_debug);
903 SET_ITEM_INT(write_bytecode);
904 SET_ITEM_INT(verbose);
905 SET_ITEM_INT(quiet);
906 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200907 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100908 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400909 SET_ITEM_WSTR(stdio_encoding);
910 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100911#ifdef MS_WINDOWS
912 SET_ITEM_INT(legacy_windows_stdio);
913#endif
914 SET_ITEM_INT(skip_source_first_line);
915 SET_ITEM_WSTR(run_command);
916 SET_ITEM_WSTR(run_module);
917 SET_ITEM_WSTR(run_filename);
918 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400919 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200920 SET_ITEM_INT(pathconfig_warnings);
921 SET_ITEM_INT(_init_main);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100922
923 return dict;
924
925fail:
926 Py_DECREF(dict);
927 return NULL;
928
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100929#undef FROM_WSTRING
930#undef SET_ITEM
931#undef SET_ITEM_INT
932#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100933#undef SET_ITEM_WSTR
934#undef SET_ITEM_WSTRLIST
935}
936
937
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100938static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200939config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200940{
Victor Stinner20004952019-03-26 02:31:11 +0100941 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200942}
943
944
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100945/* Get a copy of the environment variable as wchar_t*.
946 Return 0 on success, but *dest can be NULL.
947 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200948static PyStatus
949config_get_env_dup(PyConfig *config,
950 wchar_t **dest,
951 wchar_t *wname, char *name,
952 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200953{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200954 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100955 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200956
Victor Stinner20004952019-03-26 02:31:11 +0100957 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200958 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200959 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200960 }
961
962#ifdef MS_WINDOWS
963 const wchar_t *var = _wgetenv(wname);
964 if (!var || var[0] == '\0') {
965 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200966 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200967 }
968
Victor Stinner331a6a52019-05-27 16:39:22 +0200969 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +0200970#else
971 const char *var = getenv(name);
972 if (!var || var[0] == '\0') {
973 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200974 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200975 }
976
Victor Stinner331a6a52019-05-27 16:39:22 +0200977 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +0200978#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200979}
980
981
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200982#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200983 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200984
985
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100986static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200987config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200988{
Victor Stinner022be022019-05-22 23:58:50 +0200989 if (config->_config_init != _PyConfig_INIT_COMPAT) {
990 /* Python and Isolated configuration ignore global variables */
991 return;
992 }
993
Victor Stinner6c785c02018-08-01 17:56:14 +0200994#define COPY_FLAG(ATTR, VALUE) \
995 if (config->ATTR == -1) { \
996 config->ATTR = VALUE; \
997 }
998#define COPY_NOT_FLAG(ATTR, VALUE) \
999 if (config->ATTR == -1) { \
1000 config->ATTR = !(VALUE); \
1001 }
1002
Victor Stinner20004952019-03-26 02:31:11 +01001003 COPY_FLAG(isolated, Py_IsolatedFlag);
1004 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001005 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1006 COPY_FLAG(inspect, Py_InspectFlag);
1007 COPY_FLAG(interactive, Py_InteractiveFlag);
1008 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1009 COPY_FLAG(parser_debug, Py_DebugFlag);
1010 COPY_FLAG(verbose, Py_VerboseFlag);
1011 COPY_FLAG(quiet, Py_QuietFlag);
1012#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001013 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1014#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001015 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001016
Victor Stinner6c785c02018-08-01 17:56:14 +02001017 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1018 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1019 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1020 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1021
Victor Stinner6c785c02018-08-01 17:56:14 +02001022#undef COPY_FLAG
1023#undef COPY_NOT_FLAG
1024}
1025
1026
1027/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001028static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001029config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001030{
1031#define COPY_FLAG(ATTR, VAR) \
1032 if (config->ATTR != -1) { \
1033 VAR = config->ATTR; \
1034 }
1035#define COPY_NOT_FLAG(ATTR, VAR) \
1036 if (config->ATTR != -1) { \
1037 VAR = !config->ATTR; \
1038 }
1039
Victor Stinner20004952019-03-26 02:31:11 +01001040 COPY_FLAG(isolated, Py_IsolatedFlag);
1041 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001042 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1043 COPY_FLAG(inspect, Py_InspectFlag);
1044 COPY_FLAG(interactive, Py_InteractiveFlag);
1045 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1046 COPY_FLAG(parser_debug, Py_DebugFlag);
1047 COPY_FLAG(verbose, Py_VerboseFlag);
1048 COPY_FLAG(quiet, Py_QuietFlag);
1049#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001050 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1051#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001052 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001053
Victor Stinner6c785c02018-08-01 17:56:14 +02001054 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1055 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1056 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1057 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1058
Victor Stinner6c785c02018-08-01 17:56:14 +02001059 /* Random or non-zero hash seed */
1060 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1061 config->hash_seed != 0);
1062
1063#undef COPY_FLAG
1064#undef COPY_NOT_FLAG
1065}
1066
1067
1068/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1069 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001070static PyStatus
1071config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001072{
Victor Stinner331a6a52019-05-27 16:39:22 +02001073 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001074
Victor Stinner6c785c02018-08-01 17:56:14 +02001075 /* If Py_SetProgramName() was called, use its value */
1076 const wchar_t *program_name = _Py_path_config.program_name;
1077 if (program_name != NULL) {
1078 config->program_name = _PyMem_RawWcsdup(program_name);
1079 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001080 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001081 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001082 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001083 }
1084
1085#ifdef __APPLE__
1086 /* On MacOS X, when the Python interpreter is embedded in an
1087 application bundle, it gets executed by a bootstrapping script
1088 that does os.execve() with an argv[0] that's different from the
1089 actual Python executable. This is needed to keep the Finder happy,
1090 or rather, to work around Apple's overly strict requirements of
1091 the process name. However, we still need a usable sys.executable,
1092 so the actual executable path is passed in an environment variable.
1093 See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
1094 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001095 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001096 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001097 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1098 "PYTHONEXECUTABLE environment variable");
1099 if (_PyStatus_EXCEPTION(status)) {
1100 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001101 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001102 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001103 }
1104#ifdef WITH_NEXT_FRAMEWORK
1105 else {
1106 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1107 if (pyvenv_launcher && *pyvenv_launcher) {
1108 /* Used by Mac/Tools/pythonw.c to forward
1109 * the argv0 of the stub executable
1110 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001111 status = CONFIG_SET_BYTES_STR(config,
1112 &config->program_name,
1113 pyvenv_launcher,
1114 "__PYVENV_LAUNCHER__ environment variable");
1115 if (_PyStatus_EXCEPTION(status)) {
1116 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001117 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001118 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001119 }
1120 }
1121#endif /* WITH_NEXT_FRAMEWORK */
1122#endif /* __APPLE__ */
1123
Victor Stinnerfed02e12019-05-17 11:12:09 +02001124 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001125 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001126 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1127 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1128 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001129 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001130 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001131 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001132 }
1133
Victor Stinnerfed02e12019-05-17 11:12:09 +02001134 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001135#ifdef MS_WINDOWS
1136 const wchar_t *default_program_name = L"python";
1137#else
1138 const wchar_t *default_program_name = L"python3";
1139#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001140 status = PyConfig_SetString(config, &config->program_name,
1141 default_program_name);
1142 if (_PyStatus_EXCEPTION(status)) {
1143 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001144 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001145 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001146}
1147
Victor Stinner331a6a52019-05-27 16:39:22 +02001148static PyStatus
1149config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001150{
1151 assert(config->executable == NULL);
1152
1153 /* If Py_SetProgramFullPath() was called, use its value */
1154 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1155 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001156 PyStatus status = PyConfig_SetString(config,
1157 &config->executable,
1158 program_full_path);
1159 if (_PyStatus_EXCEPTION(status)) {
1160 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001161 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001162 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001163 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001164 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001165}
Victor Stinner6c785c02018-08-01 17:56:14 +02001166
Victor Stinner4fffd382019-03-06 01:44:31 +01001167
Victor Stinner6c785c02018-08-01 17:56:14 +02001168static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001169config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001170{
Victor Stinner74f65682019-03-15 15:08:05 +01001171 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001172}
1173
1174
Victor Stinner331a6a52019-05-27 16:39:22 +02001175static PyStatus
1176config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001177{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001178 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001179
1180 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001181 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001182 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001183 PyStatus status = PyConfig_SetString(config, &config->home, home);
1184 if (_PyStatus_EXCEPTION(status)) {
1185 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001186 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001187 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001188 }
1189
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001190 return CONFIG_GET_ENV_DUP(config, &config->home,
1191 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001192}
1193
1194
Victor Stinner331a6a52019-05-27 16:39:22 +02001195static PyStatus
1196config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001197{
Victor Stinner331a6a52019-05-27 16:39:22 +02001198 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001199
1200 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1201 /* Convert a text seed to a numeric one */
1202 if (seed_text && strcmp(seed_text, "random") != 0) {
1203 const char *endptr = seed_text;
1204 unsigned long seed;
1205 errno = 0;
1206 seed = strtoul(seed_text, (char **)&endptr, 10);
1207 if (*endptr != '\0'
1208 || seed > 4294967295UL
1209 || (errno == ERANGE && seed == ULONG_MAX))
1210 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001211 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001212 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001213 }
1214 /* Use a specific hash */
1215 config->use_hash_seed = 1;
1216 config->hash_seed = seed;
1217 }
1218 else {
1219 /* Use a random hash */
1220 config->use_hash_seed = 0;
1221 config->hash_seed = 0;
1222 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001223 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001224}
1225
1226
Victor Stinner6c785c02018-08-01 17:56:14 +02001227static int
1228config_wstr_to_int(const wchar_t *wstr, int *result)
1229{
1230 const wchar_t *endptr = wstr;
1231 errno = 0;
1232 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1233 if (*endptr != '\0' || errno == ERANGE) {
1234 return -1;
1235 }
1236 if (value < INT_MIN || value > INT_MAX) {
1237 return -1;
1238 }
1239
1240 *result = (int)value;
1241 return 0;
1242}
1243
1244
Victor Stinner331a6a52019-05-27 16:39:22 +02001245static PyStatus
1246config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001247{
Victor Stinner331a6a52019-05-27 16:39:22 +02001248 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001249 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001250
Victor Stinner6c785c02018-08-01 17:56:14 +02001251 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001252 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1253 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1254 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1255 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001256
1257 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001258 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001259 if (dont_write_bytecode) {
1260 config->write_bytecode = 0;
1261 }
1262
1263 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001264 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001265 if (no_user_site_directory) {
1266 config->user_site_directory = 0;
1267 }
1268
1269 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001270 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001271 if (unbuffered_stdio) {
1272 config->buffered_stdio = 0;
1273 }
1274
1275#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001276 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001277 "PYTHONLEGACYWINDOWSSTDIO");
1278#endif
1279
Victor Stinner331a6a52019-05-27 16:39:22 +02001280 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001281 config->dump_refs = 1;
1282 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001283 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001284 config->malloc_stats = 1;
1285 }
1286
Victor Stinner331a6a52019-05-27 16:39:22 +02001287 if (config->pythonpath_env == NULL) {
1288 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1289 L"PYTHONPATH", "PYTHONPATH");
1290 if (_PyStatus_EXCEPTION(status)) {
1291 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001292 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001293 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001294
1295 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001296 status = config_init_hash_seed(config);
1297 if (_PyStatus_EXCEPTION(status)) {
1298 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001299 }
1300 }
1301
Victor Stinner331a6a52019-05-27 16:39:22 +02001302 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001303}
1304
1305
Victor Stinner331a6a52019-05-27 16:39:22 +02001306static PyStatus
1307config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001308{
1309 int nframe;
1310 int valid;
1311
Victor Stinner331a6a52019-05-27 16:39:22 +02001312 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001313 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001314 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001315 valid = (nframe >= 0);
1316 }
1317 else {
1318 valid = 0;
1319 }
1320 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001321 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001322 }
1323 config->tracemalloc = nframe;
1324 }
1325
1326 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1327 if (xoption) {
1328 const wchar_t *sep = wcschr(xoption, L'=');
1329 if (sep) {
1330 if (!config_wstr_to_int(sep + 1, &nframe)) {
1331 valid = (nframe >= 0);
1332 }
1333 else {
1334 valid = 0;
1335 }
1336 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001337 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1338 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001339 }
1340 }
1341 else {
1342 /* -X tracemalloc behaves as -X tracemalloc=1 */
1343 nframe = 1;
1344 }
1345 config->tracemalloc = nframe;
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_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001353{
1354 assert(config->pycache_prefix == NULL);
1355
1356 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1357 if (xoption) {
1358 const wchar_t *sep = wcschr(xoption, L'=');
1359 if (sep && wcslen(sep) > 1) {
1360 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1361 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001362 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001363 }
1364 }
1365 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001366 // PYTHONPYCACHEPREFIX env var ignored
1367 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001368 config->pycache_prefix = NULL;
1369 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001370 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001371 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001372
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001373 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1374 L"PYTHONPYCACHEPREFIX",
1375 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001376}
1377
1378
Victor Stinner331a6a52019-05-27 16:39:22 +02001379static PyStatus
1380config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001381{
1382 /* More complex options configured by env var and -X option */
1383 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001384 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001385 || config_get_xoption(config, L"faulthandler")) {
1386 config->faulthandler = 1;
1387 }
1388 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001389 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001390 || config_get_xoption(config, L"importtime")) {
1391 config->import_time = 1;
1392 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001393
Victor Stinner331a6a52019-05-27 16:39:22 +02001394 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001395 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001396 status = config_init_tracemalloc(config);
1397 if (_PyStatus_EXCEPTION(status)) {
1398 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001399 }
1400 }
1401
1402 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001403 status = config_init_pycache_prefix(config);
1404 if (_PyStatus_EXCEPTION(status)) {
1405 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001406 }
1407 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001408 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001409}
1410
1411
Victor Stinner709d23d2019-05-02 14:56:30 -04001412static const wchar_t *
Victor Stinner331a6a52019-05-27 16:39:22 +02001413config_get_stdio_errors(const PyConfig *config)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001414{
1415#ifndef MS_WINDOWS
1416 const char *loc = setlocale(LC_CTYPE, NULL);
1417 if (loc != NULL) {
1418 /* surrogateescape is the default in the legacy C and POSIX locales */
1419 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001420 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001421 }
1422
1423#ifdef PY_COERCE_C_LOCALE
1424 /* surrogateescape is the default in locale coercion target locales */
1425 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001426 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001427 }
1428#endif
1429 }
1430
Victor Stinner709d23d2019-05-02 14:56:30 -04001431 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001432#else
1433 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001434 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001435#endif
1436}
1437
1438
Victor Stinner331a6a52019-05-27 16:39:22 +02001439static PyStatus
1440config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001441{
1442#ifdef MS_WINDOWS
1443 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001444 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001445 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001446#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001447 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001448#else
1449 const char *encoding = nl_langinfo(CODESET);
1450 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001451 return _PyStatus_ERR("failed to get the locale encoding: "
1452 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001453 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001454 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001455 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001456 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001457 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001458#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001459}
1460
1461
Victor Stinner331a6a52019-05-27 16:39:22 +02001462static PyStatus
1463config_init_stdio_encoding(PyConfig *config,
1464 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001465{
Victor Stinner331a6a52019-05-27 16:39:22 +02001466 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001467
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001468 /* If Py_SetStandardStreamEncoding() have been called, use these
1469 parameters. */
1470 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001471 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1472 _Py_StandardStreamEncoding,
1473 "_Py_StandardStreamEncoding");
1474 if (_PyStatus_EXCEPTION(status)) {
1475 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001476 }
1477 }
1478
1479 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001480 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1481 _Py_StandardStreamErrors,
1482 "_Py_StandardStreamErrors");
1483 if (_PyStatus_EXCEPTION(status)) {
1484 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001485 }
1486 }
1487
1488 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001489 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001490 }
1491
1492 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001493 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001494 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001495 char *pythonioencoding = _PyMem_RawStrdup(opt);
1496 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001497 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001498 }
1499
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001500 char *errors = strchr(pythonioencoding, ':');
1501 if (errors) {
1502 *errors = '\0';
1503 errors++;
1504 if (!errors[0]) {
1505 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001506 }
1507 }
1508
1509 /* Does PYTHONIOENCODING contain an encoding? */
1510 if (pythonioencoding[0]) {
1511 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001512 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1513 pythonioencoding,
1514 "PYTHONIOENCODING environment variable");
1515 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001516 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001517 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001518 }
1519 }
1520
1521 /* If the encoding is set but not the error handler,
1522 use "strict" error handler by default.
1523 PYTHONIOENCODING=latin1 behaves as
1524 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001525 if (!errors) {
1526 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001527 }
1528 }
1529
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001530 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001531 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1532 errors,
1533 "PYTHONIOENCODING environment variable");
1534 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001535 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001536 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001537 }
1538 }
1539
1540 PyMem_RawFree(pythonioencoding);
1541 }
1542
1543 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001544 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001545 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001546 status = PyConfig_SetString(config, &config->stdio_encoding,
1547 L"utf-8");
1548 if (_PyStatus_EXCEPTION(status)) {
1549 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001550 }
1551 }
1552 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001553 status = PyConfig_SetString(config, &config->stdio_errors,
1554 L"surrogateescape");
1555 if (_PyStatus_EXCEPTION(status)) {
1556 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001557 }
1558 }
1559 }
1560
1561 /* Choose the default error handler based on the current locale. */
1562 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001563 status = config_get_locale_encoding(config, &config->stdio_encoding);
1564 if (_PyStatus_EXCEPTION(status)) {
1565 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001566 }
1567 }
1568 if (config->stdio_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001569 const wchar_t *errors = config_get_stdio_errors(config);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001570 assert(errors != NULL);
1571
Victor Stinner331a6a52019-05-27 16:39:22 +02001572 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1573 if (_PyStatus_EXCEPTION(status)) {
1574 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001575 }
1576 }
1577
Victor Stinner331a6a52019-05-27 16:39:22 +02001578 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001579}
1580
1581
Victor Stinner331a6a52019-05-27 16:39:22 +02001582static PyStatus
1583config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001584{
Victor Stinner331a6a52019-05-27 16:39:22 +02001585 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001586
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001587 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001588#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001589 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001590#else
Victor Stinnere2510952019-05-02 11:28:57 -04001591
1592#ifdef MS_WINDOWS
1593 if (preconfig->legacy_windows_fs_encoding) {
1594 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001595 status = PyConfig_SetString(config, &config->filesystem_encoding,
1596 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001597 }
1598 else
1599#endif
Victor Stinner20004952019-03-26 02:31:11 +01001600 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001601 status = PyConfig_SetString(config, &config->filesystem_encoding,
1602 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001603 }
Victor Stinnere2510952019-05-02 11:28:57 -04001604#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001605 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001606 status = PyConfig_SetString(config, &config->filesystem_encoding,
1607 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001608 }
Victor Stinnere2510952019-05-02 11:28:57 -04001609#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001610 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001611#ifdef MS_WINDOWS
1612 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001613 status = PyConfig_SetString(config, &config->filesystem_encoding,
1614 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001615#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001616 status = config_get_locale_encoding(config,
1617 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001618#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001619 }
Victor Stinnere2510952019-05-02 11:28:57 -04001620#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001621
Victor Stinner331a6a52019-05-27 16:39:22 +02001622 if (_PyStatus_EXCEPTION(status)) {
1623 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001624 }
1625 }
1626
1627 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001628 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001629#ifdef MS_WINDOWS
1630 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001631 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001632 }
1633 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001634 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001635 }
1636#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001637 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001638#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001639 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1640 if (_PyStatus_EXCEPTION(status)) {
1641 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001642 }
1643 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001644 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001645}
1646
1647
Victor Stinner331a6a52019-05-27 16:39:22 +02001648static PyStatus
1649config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001650{
Victor Stinner331a6a52019-05-27 16:39:22 +02001651 PyStatus status;
1652 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001653
Victor Stinner20004952019-03-26 02:31:11 +01001654 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001655 status = config_read_env_vars(config);
1656 if (_PyStatus_EXCEPTION(status)) {
1657 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001658 }
1659 }
1660
1661 /* -X options */
1662 if (config_get_xoption(config, L"showrefcount")) {
1663 config->show_ref_count = 1;
1664 }
1665 if (config_get_xoption(config, L"showalloccount")) {
1666 config->show_alloc_count = 1;
1667 }
1668
Victor Stinner331a6a52019-05-27 16:39:22 +02001669 status = config_read_complex_options(config);
1670 if (_PyStatus_EXCEPTION(status)) {
1671 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001672 }
1673
Victor Stinner6c785c02018-08-01 17:56:14 +02001674 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001675 status = config_init_home(config);
1676 if (_PyStatus_EXCEPTION(status)) {
1677 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001678 }
1679 }
1680
Steve Dower177a41a2018-11-17 20:41:48 -08001681 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001682 status = config_init_executable(config);
1683 if (_PyStatus_EXCEPTION(status)) {
1684 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001685 }
1686 }
1687
Victor Stinner6c785c02018-08-01 17:56:14 +02001688 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001689 status = _PyConfig_InitPathConfig(config);
1690 if (_PyStatus_EXCEPTION(status)) {
1691 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001692 }
1693 }
1694
1695 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001696 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001697 if (config->faulthandler < 0) {
1698 config->faulthandler = 1;
1699 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001700 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001701 if (config->faulthandler < 0) {
1702 config->faulthandler = 0;
1703 }
1704 if (config->tracemalloc < 0) {
1705 config->tracemalloc = 0;
1706 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001707 if (config->use_hash_seed < 0) {
1708 config->use_hash_seed = 0;
1709 config->hash_seed = 0;
1710 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001711
Victor Stinner70fead22018-08-29 13:45:34 +02001712 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001713 status = config_init_fs_encoding(config, preconfig);
1714 if (_PyStatus_EXCEPTION(status)) {
1715 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001716 }
1717 }
1718
Victor Stinner331a6a52019-05-27 16:39:22 +02001719 status = config_init_stdio_encoding(config, preconfig);
1720 if (_PyStatus_EXCEPTION(status)) {
1721 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001722 }
1723
Victor Stinner62599762019-03-15 16:03:23 +01001724 if (config->argv.length < 1) {
1725 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001726 status = PyWideStringList_Append(&config->argv, L"");
1727 if (_PyStatus_EXCEPTION(status)) {
1728 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001729 }
1730 }
Victor Stinner870b0352019-05-17 03:15:12 +02001731
1732 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001733 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1734 L"default");
1735 if (_PyStatus_EXCEPTION(status)) {
1736 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001737 }
1738 }
1739
1740 if (config->configure_c_stdio < 0) {
1741 config->configure_c_stdio = 1;
1742 }
1743
Victor Stinner331a6a52019-05-27 16:39:22 +02001744 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001745}
Victor Stinner5ed69952018-11-06 15:59:52 +01001746
1747
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001748static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001749config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001750{
1751#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1752 /* don't translate newlines (\r\n <=> \n) */
1753 _setmode(fileno(stdin), O_BINARY);
1754 _setmode(fileno(stdout), O_BINARY);
1755 _setmode(fileno(stderr), O_BINARY);
1756#endif
1757
1758 if (!config->buffered_stdio) {
1759#ifdef HAVE_SETVBUF
1760 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1761 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1762 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1763#else /* !HAVE_SETVBUF */
1764 setbuf(stdin, (char *)NULL);
1765 setbuf(stdout, (char *)NULL);
1766 setbuf(stderr, (char *)NULL);
1767#endif /* !HAVE_SETVBUF */
1768 }
1769 else if (config->interactive) {
1770#ifdef MS_WINDOWS
1771 /* Doesn't have to have line-buffered -- use unbuffered */
1772 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1773 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1774#else /* !MS_WINDOWS */
1775#ifdef HAVE_SETVBUF
1776 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1777 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1778#endif /* HAVE_SETVBUF */
1779#endif /* !MS_WINDOWS */
1780 /* Leave stderr alone - it should be unbuffered anyway. */
1781 }
1782}
1783
1784
1785/* Write the configuration:
1786
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001787 - set Py_xxx global configuration variables
1788 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001789void
Victor Stinner331a6a52019-05-27 16:39:22 +02001790_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001791{
Victor Stinner331a6a52019-05-27 16:39:22 +02001792 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001793
1794 if (config->configure_c_stdio) {
1795 config_init_stdio(config);
1796 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001797
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001798 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001799 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001800 preconfig->isolated = config->isolated;
1801 preconfig->use_environment = config->use_environment;
1802 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001803}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001804
1805
Victor Stinner331a6a52019-05-27 16:39:22 +02001806/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001807
1808static void
Victor Stinner2f549082019-03-29 15:13:46 +01001809config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001810{
Victor Stinner2f549082019-03-29 15:13:46 +01001811 FILE *f = error ? stderr : stdout;
1812
1813 fprintf(f, usage_line, program);
1814 if (error)
1815 fprintf(f, "Try `python -h' for more information.\n");
1816 else {
1817 fputs(usage_1, f);
1818 fputs(usage_2, f);
1819 fputs(usage_3, f);
1820 fprintf(f, usage_4, (wint_t)DELIM);
1821 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1822 fputs(usage_6, f);
1823 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001824}
1825
1826
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001827/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001828static PyStatus
1829config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001830 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001831{
Victor Stinner331a6a52019-05-27 16:39:22 +02001832 PyStatus status;
1833 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001834 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001835 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001836
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001837 _PyOS_ResetGetOpt();
1838 do {
1839 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001840 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001841 if (c == EOF) {
1842 break;
1843 }
1844
1845 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001846 if (config->run_command == NULL) {
1847 /* -c is the last option; following arguments
1848 that look like options are left for the
1849 command to interpret. */
1850 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1851 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1852 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001853 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001854 }
1855 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1856 command[len - 2] = '\n';
1857 command[len - 1] = 0;
1858 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001859 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001860 break;
1861 }
1862
1863 if (c == 'm') {
1864 /* -m is the last option; following arguments
1865 that look like options are left for the
1866 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001867 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001868 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1869 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001870 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001871 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001872 }
1873 break;
1874 }
1875
1876 switch (c) {
1877 case 0:
1878 // Handle long option.
1879 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001880 if (wcscmp(_PyOS_optarg, L"always") == 0
1881 || wcscmp(_PyOS_optarg, L"never") == 0
1882 || wcscmp(_PyOS_optarg, L"default") == 0)
1883 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001884 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1885 _PyOS_optarg);
1886 if (_PyStatus_EXCEPTION(status)) {
1887 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001888 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001889 } else {
1890 fprintf(stderr, "--check-hash-based-pycs must be one of "
1891 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001892 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001893 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001894 }
1895 break;
1896
1897 case 'b':
1898 config->bytes_warning++;
1899 break;
1900
1901 case 'd':
1902 config->parser_debug++;
1903 break;
1904
1905 case 'i':
1906 config->inspect++;
1907 config->interactive++;
1908 break;
1909
Victor Stinner6dcb5422019-03-05 02:44:12 +01001910 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001911 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001912 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001913 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001914 break;
1915
1916 /* case 'J': reserved for Jython */
1917
1918 case 'O':
1919 config->optimization_level++;
1920 break;
1921
1922 case 'B':
1923 config->write_bytecode = 0;
1924 break;
1925
1926 case 's':
1927 config->user_site_directory = 0;
1928 break;
1929
1930 case 'S':
1931 config->site_import = 0;
1932 break;
1933
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001934 case 't':
1935 /* ignored for backwards compatibility */
1936 break;
1937
1938 case 'u':
1939 config->buffered_stdio = 0;
1940 break;
1941
1942 case 'v':
1943 config->verbose++;
1944 break;
1945
1946 case 'x':
1947 config->skip_source_first_line = 1;
1948 break;
1949
1950 case 'h':
1951 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001952 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001953 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001954
1955 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01001956 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001957 break;
1958
1959 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02001960 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
1961 if (_PyStatus_EXCEPTION(status)) {
1962 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001963 }
1964 break;
1965
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001966 case 'q':
1967 config->quiet++;
1968 break;
1969
1970 case 'R':
1971 config->use_hash_seed = 0;
1972 break;
1973
1974 /* This space reserved for other options */
1975
1976 default:
1977 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02001978 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001979 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001980 }
1981 } while (1);
1982
Victor Stinner2f549082019-03-29 15:13:46 +01001983 if (print_version) {
1984 printf("Python %s\n",
1985 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02001986 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01001987 }
1988
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001989 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01001990 && _PyOS_optind < argv->length
1991 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01001992 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001993 {
Victor Stinnerfa153762019-03-20 04:25:38 +01001994 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001995 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001996 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001997 }
1998 }
1999
2000 if (config->run_command != NULL || config->run_module != NULL) {
2001 /* Backup _PyOS_optind */
2002 _PyOS_optind--;
2003 }
2004
Victor Stinnerae239f62019-05-16 17:02:56 +02002005 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002006
Victor Stinner331a6a52019-05-27 16:39:22 +02002007 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002008}
2009
2010
2011#ifdef MS_WINDOWS
2012# define WCSTOK wcstok_s
2013#else
2014# define WCSTOK wcstok
2015#endif
2016
2017/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002018static PyStatus
2019config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002020{
Victor Stinner331a6a52019-05-27 16:39:22 +02002021 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002022 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2023 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002024 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002025 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002026 if (_PyStatus_EXCEPTION(status)) {
2027 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002028 }
2029
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002030 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002031 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002032 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002033 }
2034
2035
2036 wchar_t *warning, *context = NULL;
2037 for (warning = WCSTOK(env, L",", &context);
2038 warning != NULL;
2039 warning = WCSTOK(NULL, L",", &context))
2040 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002041 status = PyWideStringList_Append(warnoptions, warning);
2042 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002043 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002044 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002045 }
2046 }
2047 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002048 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002049}
2050
2051
Victor Stinner331a6a52019-05-27 16:39:22 +02002052static PyStatus
2053config_add_warnoption(PyConfig *config, const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002054{
Victor Stinner331a6a52019-05-27 16:39:22 +02002055 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002056 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002057 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002058 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002059 return PyWideStringList_Append(&config->warnoptions, option);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002060}
2061
2062
Victor Stinner331a6a52019-05-27 16:39:22 +02002063static PyStatus
2064config_init_warnoptions(PyConfig *config,
2065 const PyWideStringList *cmdline_warnoptions,
2066 const PyWideStringList *env_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002067{
Victor Stinner331a6a52019-05-27 16:39:22 +02002068 PyStatus status;
2069
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002070 /* The priority order for warnings configuration is (highest precedence
2071 * first):
2072 *
Victor Stinneraf84a882019-08-23 21:16:51 +02002073 * - early PySys_AddWarnOption() calls
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002074 * - the BytesWarning filter, if needed ('-b', '-bb')
2075 * - any '-W' command line options; then
2076 * - the 'PYTHONWARNINGS' environment variable; then
2077 * - the dev mode filter ('-X dev', 'PYTHONDEVMODE'); then
2078 * - any implicit filters added by _warnings.c/warnings.py
2079 *
2080 * All settings except the last are passed to the warnings module via
2081 * the `sys.warnoptions` list. Since the warnings module works on the basis
2082 * of "the most recently added filter will be checked first", we add
2083 * the lowest precedence entries first so that later entries override them.
2084 */
2085
Victor Stinner20004952019-03-26 02:31:11 +01002086 if (config->dev_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002087 status = config_add_warnoption(config, L"default");
2088 if (_PyStatus_EXCEPTION(status)) {
2089 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002090 }
2091 }
2092
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002093 Py_ssize_t i;
Victor Stinner331a6a52019-05-27 16:39:22 +02002094 const PyWideStringList *options;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002095
Victor Stinner2f549082019-03-29 15:13:46 +01002096 options = env_warnoptions;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002097 for (i = 0; i < options->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002098 status = config_add_warnoption(config, options->items[i]);
2099 if (_PyStatus_EXCEPTION(status)) {
2100 return status;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002101 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002102 }
2103
Victor Stinner2f549082019-03-29 15:13:46 +01002104 options = cmdline_warnoptions;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002105 for (i = 0; i < options->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002106 status = config_add_warnoption(config, options->items[i]);
2107 if (_PyStatus_EXCEPTION(status)) {
2108 return status;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002109 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002110 }
2111
2112 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2113 * don't even try to emit a warning, so we skip setting the filter in that
2114 * case.
2115 */
2116 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002117 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002118 if (config->bytes_warning> 1) {
2119 filter = L"error::BytesWarning";
2120 }
2121 else {
2122 filter = L"default::BytesWarning";
2123 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002124 status = config_add_warnoption(config, filter);
2125 if (_PyStatus_EXCEPTION(status)) {
2126 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002127 }
2128 }
Victor Stinneraf84a882019-08-23 21:16:51 +02002129
2130 /* Handle early PySys_AddWarnOption() calls */
2131 status = _PySys_ReadPreinitWarnOptions(config);
2132 if (_PyStatus_EXCEPTION(status)) {
2133 return status;
2134 }
2135
Victor Stinner331a6a52019-05-27 16:39:22 +02002136 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002137}
2138
2139
Victor Stinner331a6a52019-05-27 16:39:22 +02002140static PyStatus
2141config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002142{
Victor Stinner331a6a52019-05-27 16:39:22 +02002143 const PyWideStringList *cmdline_argv = &config->argv;
2144 PyWideStringList config_argv = PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002145
Victor Stinner74f65682019-03-15 15:08:05 +01002146 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002147 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002148 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002149 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2150 if (_PyStatus_EXCEPTION(status)) {
2151 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002152 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002153 }
2154 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002155 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002156 slice.length = cmdline_argv->length - opt_index;
2157 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002158 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2159 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002160 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002161 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002162 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002163
2164 wchar_t *arg0 = NULL;
2165 if (config->run_command != NULL) {
2166 /* Force sys.argv[0] = '-c' */
2167 arg0 = L"-c";
2168 }
2169 else if (config->run_module != NULL) {
2170 /* Force sys.argv[0] = '-m'*/
2171 arg0 = L"-m";
2172 }
2173 if (arg0 != NULL) {
2174 arg0 = _PyMem_RawWcsdup(arg0);
2175 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002176 _PyWideStringList_Clear(&config_argv);
2177 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002178 }
2179
Victor Stinnerfa153762019-03-20 04:25:38 +01002180 PyMem_RawFree(config_argv.items[0]);
2181 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002182 }
2183
Victor Stinner331a6a52019-05-27 16:39:22 +02002184 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002185 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002186 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002187}
2188
2189
Victor Stinner331a6a52019-05-27 16:39:22 +02002190static PyStatus
2191core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002192{
Victor Stinner331a6a52019-05-27 16:39:22 +02002193 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002194
Victor Stinnercab5d072019-05-17 19:01:14 +02002195 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002196 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2197 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002198 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002199 }
2200
Victor Stinner331a6a52019-05-27 16:39:22 +02002201 PyPreConfig preconfig;
Victor Stinner6d1c4672019-05-20 11:02:00 +02002202 _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002203
Victor Stinner331a6a52019-05-27 16:39:22 +02002204 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002205
Victor Stinner331a6a52019-05-27 16:39:22 +02002206 status = _PyPreCmdline_Read(precmdline, &preconfig);
2207 if (_PyStatus_EXCEPTION(status)) {
2208 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002209 }
2210
Victor Stinner331a6a52019-05-27 16:39:22 +02002211 status = _PyPreCmdline_SetConfig(precmdline, config);
2212 if (_PyStatus_EXCEPTION(status)) {
2213 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002214 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002215 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002216}
2217
2218
Victor Stinner331a6a52019-05-27 16:39:22 +02002219static PyStatus
2220config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002221{
Victor Stinner331a6a52019-05-27 16:39:22 +02002222 PyStatus status;
2223 PyWideStringList cmdline_warnoptions = PyWideStringList_INIT;
2224 PyWideStringList env_warnoptions = PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002225
Victor Stinnerae239f62019-05-16 17:02:56 +02002226 if (config->parse_argv < 0) {
2227 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002228 }
Victor Stinner870b0352019-05-17 03:15:12 +02002229
Victor Stinnerfed02e12019-05-17 11:12:09 +02002230 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002231 status = config_init_program_name(config);
2232 if (_PyStatus_EXCEPTION(status)) {
2233 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002234 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002235 }
Victor Stinner2f549082019-03-29 15:13:46 +01002236
Victor Stinnerae239f62019-05-16 17:02:56 +02002237 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002238 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002239 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2240 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002241 goto done;
2242 }
2243
Victor Stinner331a6a52019-05-27 16:39:22 +02002244 status = config_update_argv(config, opt_index);
2245 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002246 goto done;
2247 }
Victor Stinner2f549082019-03-29 15:13:46 +01002248 }
2249
Victor Stinner2f549082019-03-29 15:13:46 +01002250 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002251 status = config_init_env_warnoptions(config, &env_warnoptions);
2252 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002253 goto done;
2254 }
2255 }
2256
Victor Stinner331a6a52019-05-27 16:39:22 +02002257 status = config_init_warnoptions(config,
Victor Stinneraf84a882019-08-23 21:16:51 +02002258 &cmdline_warnoptions,
2259 &env_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002260 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002261 goto done;
2262 }
2263
Victor Stinner331a6a52019-05-27 16:39:22 +02002264 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002265
2266done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002267 _PyWideStringList_Clear(&cmdline_warnoptions);
2268 _PyWideStringList_Clear(&env_warnoptions);
2269 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002270}
2271
2272
Victor Stinner331a6a52019-05-27 16:39:22 +02002273PyStatus
2274_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002275{
Victor Stinner331a6a52019-05-27 16:39:22 +02002276 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2277 if (_PyStatus_EXCEPTION(status)) {
2278 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002279 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002280
Victor Stinner5f38b842019-05-01 02:30:12 +02002281 return _PyArgv_AsWstrList(args, &config->argv);
2282}
2283
2284
Victor Stinner70005ac2019-05-02 15:25:34 -04002285/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2286 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002287PyStatus
2288PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002289{
2290 _PyArgv args = {
2291 .argc = argc,
2292 .use_bytes_argv = 1,
2293 .bytes_argv = argv,
2294 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002295 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002296}
2297
2298
Victor Stinner331a6a52019-05-27 16:39:22 +02002299PyStatus
2300PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002301{
2302 _PyArgv args = {
2303 .argc = argc,
2304 .use_bytes_argv = 0,
2305 .bytes_argv = NULL,
2306 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002307 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002308}
2309
2310
Miss Islington (bot)96f581c2019-07-01 10:39:58 -07002311PyStatus
2312PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2313 Py_ssize_t length, wchar_t **items)
2314{
2315 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2316 if (_PyStatus_EXCEPTION(status)) {
2317 return status;
2318 }
2319
2320 PyWideStringList list2 = {.length = length, .items = items};
2321 if (_PyWideStringList_Copy(list, &list2) < 0) {
2322 return _PyStatus_NO_MEMORY();
2323 }
2324 return _PyStatus_OK();
2325}
2326
2327
Victor Stinner331a6a52019-05-27 16:39:22 +02002328/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002329
2330 * Command line arguments
2331 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002332 * Py_xxx global configuration variables
2333
2334 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002335PyStatus
2336PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002337{
Victor Stinner331a6a52019-05-27 16:39:22 +02002338 PyStatus status;
2339 PyWideStringList orig_argv = PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002340
Victor Stinner331a6a52019-05-27 16:39:22 +02002341 status = _Py_PreInitializeFromConfig(config, NULL);
2342 if (_PyStatus_EXCEPTION(status)) {
2343 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002344 }
2345
Victor Stinner331a6a52019-05-27 16:39:22 +02002346 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002347
Victor Stinner331a6a52019-05-27 16:39:22 +02002348 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2349 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002350 }
2351
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002352 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002353 status = core_read_precmdline(config, &precmdline);
2354 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002355 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002356 }
2357
Victor Stinner870b0352019-05-17 03:15:12 +02002358 assert(config->isolated >= 0);
2359 if (config->isolated) {
2360 config->use_environment = 0;
2361 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002362 }
2363
Victor Stinner331a6a52019-05-27 16:39:22 +02002364 status = config_read_cmdline(config);
2365 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002366 goto done;
2367 }
2368
Victor Stinneraf84a882019-08-23 21:16:51 +02002369 /* Handle early PySys_AddXOption() calls */
2370 status = _PySys_ReadPreinitXOptions(config);
2371 if (_PyStatus_EXCEPTION(status)) {
2372 goto done;
2373 }
2374
Victor Stinner331a6a52019-05-27 16:39:22 +02002375 status = config_read(config);
2376 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002377 goto done;
2378 }
2379
Victor Stinnercab5d072019-05-17 19:01:14 +02002380 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002381 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002382 goto done;
2383 }
2384
2385 /* Check config consistency */
2386 assert(config->isolated >= 0);
2387 assert(config->use_environment >= 0);
2388 assert(config->dev_mode >= 0);
2389 assert(config->install_signal_handlers >= 0);
2390 assert(config->use_hash_seed >= 0);
2391 assert(config->faulthandler >= 0);
2392 assert(config->tracemalloc >= 0);
2393 assert(config->site_import >= 0);
2394 assert(config->bytes_warning >= 0);
2395 assert(config->inspect >= 0);
2396 assert(config->interactive >= 0);
2397 assert(config->optimization_level >= 0);
2398 assert(config->parser_debug >= 0);
2399 assert(config->write_bytecode >= 0);
2400 assert(config->verbose >= 0);
2401 assert(config->quiet >= 0);
2402 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002403 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002404 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002405 assert(config->buffered_stdio >= 0);
2406 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002407 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002408 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2409 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002410 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2411 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2412 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002413 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002414 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002415 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002416 assert(config->executable != NULL);
Steve Dower323e7432019-06-29 14:28:59 -07002417 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002418 assert(config->prefix != NULL);
2419 assert(config->base_prefix != NULL);
2420 assert(config->exec_prefix != NULL);
2421 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002422 }
2423 assert(config->filesystem_encoding != NULL);
2424 assert(config->filesystem_errors != NULL);
2425 assert(config->stdio_encoding != NULL);
2426 assert(config->stdio_errors != NULL);
2427#ifdef MS_WINDOWS
2428 assert(config->legacy_windows_stdio >= 0);
2429#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002430 /* -c and -m options are exclusive */
2431 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002432 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002433 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002434 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002435
Victor Stinner331a6a52019-05-27 16:39:22 +02002436 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002437
2438done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002439 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002440 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002441 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002442}
Victor Stinner1075d162019-03-25 23:19:57 +01002443
2444
2445PyObject*
2446_Py_GetConfigsAsDict(void)
2447{
Victor Stinner331a6a52019-05-27 16:39:22 +02002448 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002449 PyObject *dict = NULL;
2450
Victor Stinner331a6a52019-05-27 16:39:22 +02002451 result = PyDict_New();
2452 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002453 goto error;
2454 }
2455
Victor Stinner331a6a52019-05-27 16:39:22 +02002456 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002457 dict = _Py_GetGlobalVariablesAsDict();
2458 if (dict == NULL) {
2459 goto error;
2460 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002461 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002462 goto error;
2463 }
2464 Py_CLEAR(dict);
2465
2466 /* pre config */
2467 PyInterpreterState *interp = _PyInterpreterState_Get();
Victor Stinner331a6a52019-05-27 16:39:22 +02002468 const PyPreConfig *pre_config = &_PyRuntime.preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002469 dict = _PyPreConfig_AsDict(pre_config);
2470 if (dict == NULL) {
2471 goto error;
2472 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002473 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002474 goto error;
2475 }
2476 Py_CLEAR(dict);
2477
2478 /* core config */
Victor Stinner331a6a52019-05-27 16:39:22 +02002479 const PyConfig *config = &interp->config;
2480 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002481 if (dict == NULL) {
2482 goto error;
2483 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002484 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002485 goto error;
2486 }
2487 Py_CLEAR(dict);
2488
Victor Stinner331a6a52019-05-27 16:39:22 +02002489 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002490
2491error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002492 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002493 Py_XDECREF(dict);
2494 return NULL;
2495}
Victor Stinnerc5c64252019-09-23 15:59:00 +02002496
2497
2498static void
2499init_dump_ascii_wstr(const wchar_t *str)
2500{
2501 if (str == NULL) {
2502 PySys_WriteStderr("(not set)");
2503 return;
2504 }
2505
2506 PySys_WriteStderr("'");
2507 for (; *str != L'\0'; str++) {
2508 wchar_t ch = *str;
2509 if (ch == L'\'') {
2510 PySys_WriteStderr("\\'");
2511 } else if (0x20 <= ch && ch < 0x7f) {
2512 PySys_WriteStderr("%lc", ch);
2513 }
2514 else if (ch <= 0xff) {
2515 PySys_WriteStderr("\\x%02x", ch);
2516 }
2517#if SIZEOF_WCHAR_T > 2
2518 else if (ch > 0xffff) {
2519 PySys_WriteStderr("\\U%08x", ch);
2520 }
2521#endif
2522 else {
2523 PySys_WriteStderr("\\u%04x", ch);
2524 }
2525 }
2526 PySys_WriteStderr("'");
2527}
2528
2529
2530/* Dump the Python path configuration into sys.stderr */
2531void
2532_Py_DumpPathConfig(PyThreadState *tstate)
2533{
2534 PyObject *exc_type, *exc_value, *exc_tb;
2535 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2536
2537 PySys_WriteStderr("Python path configuration:\n");
2538
2539#define DUMP_CONFIG(NAME, FIELD) \
2540 do { \
2541 PySys_WriteStderr(" " NAME " = "); \
2542 init_dump_ascii_wstr(config->FIELD); \
2543 PySys_WriteStderr("\n"); \
2544 } while (0)
2545
2546 PyConfig *config = &tstate->interp->config;
2547 DUMP_CONFIG("PYTHONHOME", home);
2548 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2549 DUMP_CONFIG("program name", program_name);
2550 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2551 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2552 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2553 PySys_WriteStderr(" import site = %i\n", config->site_import);
2554#undef DUMP_CONFIG
2555
2556#define DUMP_SYS(NAME) \
2557 do { \
2558 obj = PySys_GetObject(#NAME); \
2559 PySys_FormatStderr(" sys.%s = ", #NAME); \
2560 if (obj != NULL) { \
2561 PySys_FormatStderr("%A", obj); \
2562 } \
2563 else { \
2564 PySys_WriteStderr("(not set)"); \
2565 } \
2566 PySys_FormatStderr("\n"); \
2567 } while (0)
2568
2569 PyObject *obj;
2570 DUMP_SYS(_base_executable);
2571 DUMP_SYS(base_prefix);
2572 DUMP_SYS(base_exec_prefix);
2573 DUMP_SYS(executable);
2574 DUMP_SYS(prefix);
2575 DUMP_SYS(exec_prefix);
2576#undef DUMP_SYS
2577
2578 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2579 if (sys_path != NULL && PyList_Check(sys_path)) {
2580 PySys_WriteStderr(" sys.path = [\n");
2581 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2582 for (Py_ssize_t i=0; i < len; i++) {
2583 PyObject *path = PyList_GET_ITEM(sys_path, i);
2584 PySys_FormatStderr(" %A,\n", path);
2585 }
2586 PySys_WriteStderr(" ]\n");
2587 }
2588
2589 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2590}