blob: 49659045f7ab4f34910cbd1bb0abc4f296cbdfac [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 Stinner331a6a52019-05-27 16:39:22 +02003#include "pycore_initconfig.h"
Victor Stinner9fc57a32018-11-07 00:44:03 +01004#include "pycore_fileutils.h"
Victor Stinner95e2cbf2019-03-01 16:25:19 +01005#include "pycore_getopt.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01006#include "pycore_pylifecycle.h"
7#include "pycore_pymem.h"
Victor Stinner6d5ee972019-03-23 12:05:43 +01008#include "pycore_pystate.h" /* _PyRuntime */
Victor Stinnera1c249c2018-11-01 03:15:58 +01009#include "pycore_pathconfig.h"
Victor Stinner95e2cbf2019-03-01 16:25:19 +010010#include <locale.h> /* setlocale() */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020011#ifdef HAVE_LANGINFO_H
Victor Stinner95e2cbf2019-03-01 16:25:19 +010012# include <langinfo.h> /* nl_langinfo(CODESET) */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020013#endif
Victor Stinner95e2cbf2019-03-01 16:25:19 +010014#if defined(MS_WINDOWS) || defined(__CYGWIN__)
15# include <windows.h> /* GetACP() */
16# ifdef HAVE_IO_H
17# include <io.h>
18# endif
19# ifdef HAVE_FCNTL_H
20# include <fcntl.h> /* O_BINARY */
21# endif
Victor Stinnerb2457ef2018-08-29 13:25:36 +020022#endif
23
Victor Stinner6c785c02018-08-01 17:56:14 +020024
Victor Stinner95e2cbf2019-03-01 16:25:19 +010025/* --- Command line options --------------------------------------- */
26
Victor Stinner95e2cbf2019-03-01 16:25:19 +010027/* Short usage message (with %s for argv0) */
28static const char usage_line[] =
29"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
30
31/* Long usage message, split into parts < 512 bytes */
32static const char usage_1[] = "\
33Options and arguments (and corresponding environment variables):\n\
34-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
35 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
36-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
37-c cmd : program passed in as string (terminates option list)\n\
38-d : debug output from parser; also PYTHONDEBUG=x\n\
39-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
40-h : print this help message and exit (also --help)\n\
41";
42static const char usage_2[] = "\
43-i : inspect interactively after running script; forces a prompt even\n\
44 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
45-I : isolate Python from the user's environment (implies -E and -s)\n\
46-m mod : run library module as a script (terminates option list)\n\
47-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
48 .pyc extension; also PYTHONOPTIMIZE=x\n\
49-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
50 .pyc extension\n\
51-q : don't print version and copyright messages on interactive startup\n\
52-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
53-S : don't imply 'import site' on initialization\n\
54";
55static const char usage_3[] = "\
56-u : force the stdout and stderr streams to be unbuffered;\n\
57 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
58-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
59 can be supplied multiple times to increase verbosity\n\
60-V : print the Python version number and exit (also --version)\n\
61 when given twice, print more information about the build\n\
62-W arg : warning control; arg is action:message:category:module:lineno\n\
63 also PYTHONWARNINGS=arg\n\
64-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
65-X opt : set implementation-specific option\n\
66--check-hash-based-pycs always|default|never:\n\
67 control how Python invalidates hash-based .pyc files\n\
68";
69static const char usage_4[] = "\
70file : program read from script file\n\
71- : program read from stdin (default; interactive mode if a tty)\n\
72arg ...: arguments passed to program in sys.argv[1:]\n\n\
73Other environment variables:\n\
74PYTHONSTARTUP: file executed on interactive startup (no default)\n\
75PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
76 default module search path. The result is sys.path.\n\
77";
78static const char usage_5[] =
79"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
80" The default module search path uses %s.\n"
81"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
82"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
83"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
84static const char usage_6[] =
85"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Miss Islington (bot)076d0b92019-08-24 03:19:51 -070086" to seed the hashes of str and bytes objects. It can also be set to an\n"
87" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +010088" predictable seed.\n"
89"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
90" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
91" hooks.\n"
92"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
93" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
94" locale coercion and locale compatibility warnings on stderr.\n"
95"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
96" debugger. It can be set to the callable of your debugger of choice.\n"
97"PYTHONDEVMODE: enable the development mode.\n"
98"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
99
100#if defined(MS_WINDOWS)
101# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
102#else
103# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
104#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200105
106
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100107/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200108
Victor Stinner6c785c02018-08-01 17:56:14 +0200109/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200110 stdin and stdout error handler to "surrogateescape". */
111int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200112int Py_DebugFlag = 0; /* Needed by parser.c */
113int Py_VerboseFlag = 0; /* Needed by import.c */
114int Py_QuietFlag = 0; /* Needed by sysmodule.c */
115int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
116int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
117int Py_OptimizeFlag = 0; /* Needed by compile.c */
118int Py_NoSiteFlag = 0; /* Suppress 'import site' */
119int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
120int Py_FrozenFlag = 0; /* Needed by getpath.c */
121int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
122int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
123int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
124int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
125int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
126int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
127#ifdef MS_WINDOWS
128int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
129int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
130#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200131
132
Victor Stinner1075d162019-03-25 23:19:57 +0100133static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100134_Py_GetGlobalVariablesAsDict(void)
135{
136 PyObject *dict, *obj;
137
138 dict = PyDict_New();
139 if (dict == NULL) {
140 return NULL;
141 }
142
143#define SET_ITEM(KEY, EXPR) \
144 do { \
145 obj = (EXPR); \
146 if (obj == NULL) { \
147 return NULL; \
148 } \
149 int res = PyDict_SetItemString(dict, (KEY), obj); \
150 Py_DECREF(obj); \
151 if (res < 0) { \
152 goto fail; \
153 } \
154 } while (0)
155#define SET_ITEM_INT(VAR) \
156 SET_ITEM(#VAR, PyLong_FromLong(VAR))
157#define FROM_STRING(STR) \
158 ((STR != NULL) ? \
159 PyUnicode_FromString(STR) \
160 : (Py_INCREF(Py_None), Py_None))
161#define SET_ITEM_STR(VAR) \
162 SET_ITEM(#VAR, FROM_STRING(VAR))
163
164 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
165 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
166 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
167 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
168
169 SET_ITEM_INT(Py_UTF8Mode);
170 SET_ITEM_INT(Py_DebugFlag);
171 SET_ITEM_INT(Py_VerboseFlag);
172 SET_ITEM_INT(Py_QuietFlag);
173 SET_ITEM_INT(Py_InteractiveFlag);
174 SET_ITEM_INT(Py_InspectFlag);
175
176 SET_ITEM_INT(Py_OptimizeFlag);
177 SET_ITEM_INT(Py_NoSiteFlag);
178 SET_ITEM_INT(Py_BytesWarningFlag);
179 SET_ITEM_INT(Py_FrozenFlag);
180 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
181 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
182 SET_ITEM_INT(Py_NoUserSiteDirectory);
183 SET_ITEM_INT(Py_UnbufferedStdioFlag);
184 SET_ITEM_INT(Py_HashRandomizationFlag);
185 SET_ITEM_INT(Py_IsolatedFlag);
186
187#ifdef MS_WINDOWS
188 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
189 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
190#endif
191
192 return dict;
193
194fail:
195 Py_DECREF(dict);
196 return NULL;
197
198#undef FROM_STRING
199#undef SET_ITEM
200#undef SET_ITEM_INT
201#undef SET_ITEM_STR
202}
203
204
Victor Stinner331a6a52019-05-27 16:39:22 +0200205/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200206
Victor Stinner331a6a52019-05-27 16:39:22 +0200207PyStatus PyStatus_Ok(void)
208{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200209
Victor Stinner331a6a52019-05-27 16:39:22 +0200210PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200211{
Victor Stinner331a6a52019-05-27 16:39:22 +0200212 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner871ff772019-05-17 23:54:00 +0200213 .err_msg = err_msg};
214}
215
Victor Stinner331a6a52019-05-27 16:39:22 +0200216PyStatus PyStatus_NoMemory(void)
217{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200218
Victor Stinner331a6a52019-05-27 16:39:22 +0200219PyStatus PyStatus_Exit(int exitcode)
220{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200221
222
Victor Stinner331a6a52019-05-27 16:39:22 +0200223int PyStatus_IsError(PyStatus status)
224{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200225
Victor Stinner331a6a52019-05-27 16:39:22 +0200226int PyStatus_IsExit(PyStatus status)
227{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200228
Victor Stinner331a6a52019-05-27 16:39:22 +0200229int PyStatus_Exception(PyStatus status)
230{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200231
232
Victor Stinner331a6a52019-05-27 16:39:22 +0200233/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100234
235#ifndef NDEBUG
236int
Victor Stinner331a6a52019-05-27 16:39:22 +0200237_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100238{
239 assert(list->length >= 0);
240 if (list->length != 0) {
241 assert(list->items != NULL);
242 }
243 for (Py_ssize_t i = 0; i < list->length; i++) {
244 assert(list->items[i] != NULL);
245 }
246 return 1;
247}
248#endif /* Py_DEBUG */
249
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100250
Victor Stinner6c785c02018-08-01 17:56:14 +0200251void
Victor Stinner331a6a52019-05-27 16:39:22 +0200252_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200253{
Victor Stinner331a6a52019-05-27 16:39:22 +0200254 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100255 for (Py_ssize_t i=0; i < list->length; i++) {
256 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200257 }
Victor Stinner74f65682019-03-15 15:08:05 +0100258 PyMem_RawFree(list->items);
259 list->length = 0;
260 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200261}
262
263
Victor Stinner74f65682019-03-15 15:08:05 +0100264int
Victor Stinner331a6a52019-05-27 16:39:22 +0200265_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200266{
Victor Stinner331a6a52019-05-27 16:39:22 +0200267 assert(_PyWideStringList_CheckConsistency(list));
268 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100269
270 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200271 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100272 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300273 }
Victor Stinner74f65682019-03-15 15:08:05 +0100274
Victor Stinner331a6a52019-05-27 16:39:22 +0200275 PyWideStringList copy = PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100276
277 size_t size = list2->length * sizeof(list2->items[0]);
278 copy.items = PyMem_RawMalloc(size);
279 if (copy.items == NULL) {
280 return -1;
281 }
282
283 for (Py_ssize_t i=0; i < list2->length; i++) {
284 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
285 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200286 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100287 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200288 }
Victor Stinner74f65682019-03-15 15:08:05 +0100289 copy.items[i] = item;
290 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200291 }
Victor Stinner74f65682019-03-15 15:08:05 +0100292
Victor Stinner331a6a52019-05-27 16:39:22 +0200293 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100294 *list = copy;
295 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200296}
297
298
Victor Stinner331a6a52019-05-27 16:39:22 +0200299PyStatus
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700300PyWideStringList_Insert(PyWideStringList *list,
301 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100302{
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700303 Py_ssize_t len = list->length;
304 if (len == PY_SSIZE_T_MAX) {
Kyle Stanley24b5b362019-07-21 22:48:45 -0400305 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200306 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100307 }
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700308 if (index < 0) {
309 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
310 }
311 if (index > len) {
312 index = len;
313 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100314
Victor Stinner74f65682019-03-15 15:08:05 +0100315 wchar_t *item2 = _PyMem_RawWcsdup(item);
316 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200317 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100318 }
Victor Stinner74f65682019-03-15 15:08:05 +0100319
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700320 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100321 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
322 if (items2 == NULL) {
323 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200324 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100325 }
326
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700327 if (index < len) {
328 memmove(&items2[index + 1],
329 &items2[index],
330 (len - index) * sizeof(items2[0]));
331 }
332
333 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100334 list->items = items2;
335 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200336 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100337}
338
339
Victor Stinner331a6a52019-05-27 16:39:22 +0200340PyStatus
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700341PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
342{
343 return PyWideStringList_Insert(list, list->length, item);
344}
345
346
347PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200348_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100349{
350 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200351 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
352 if (_PyStatus_EXCEPTION(status)) {
353 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100354 }
355 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200356 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100357}
358
359
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100360static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200361_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100362{
363 for (Py_ssize_t i = 0; i < list->length; i++) {
364 if (wcscmp(list->items[i], item) == 0) {
365 return 1;
366 }
367 }
368 return 0;
369}
370
371
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100372PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200373_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100374{
Victor Stinner331a6a52019-05-27 16:39:22 +0200375 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100376
Victor Stinner74f65682019-03-15 15:08:05 +0100377 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100378 if (pylist == NULL) {
379 return NULL;
380 }
381
Victor Stinner74f65682019-03-15 15:08:05 +0100382 for (Py_ssize_t i = 0; i < list->length; i++) {
383 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
384 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100385 Py_DECREF(pylist);
386 return NULL;
387 }
Victor Stinner74f65682019-03-15 15:08:05 +0100388 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100389 }
390 return pylist;
391}
392
393
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100394/* --- Py_SetStandardStreamEncoding() ----------------------------- */
395
Victor Stinner124b9eb2018-08-29 01:29:06 +0200396/* Helper to allow an embedding application to override the normal
397 * mechanism that attempts to figure out an appropriate IO encoding
398 */
399
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200400static char *_Py_StandardStreamEncoding = NULL;
401static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200402
403int
404Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
405{
406 if (Py_IsInitialized()) {
407 /* This is too late to have any effect */
408 return -1;
409 }
410
411 int res = 0;
412
413 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
414 but Py_Initialize() can change the allocator. Use a known allocator
415 to be able to release the memory later. */
416 PyMemAllocatorEx old_alloc;
417 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
418
419 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
420 * initialised yet.
421 *
422 * However, the raw memory allocators are initialised appropriately
423 * as C static variables, so _PyMem_RawStrdup is OK even though
424 * Py_Initialize hasn't been called yet.
425 */
426 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200427 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200428 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
429 if (!_Py_StandardStreamEncoding) {
430 res = -2;
431 goto done;
432 }
433 }
434 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200435 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200436 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
437 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200438 PyMem_RawFree(_Py_StandardStreamEncoding);
439 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200440 res = -3;
441 goto done;
442 }
443 }
444#ifdef MS_WINDOWS
445 if (_Py_StandardStreamEncoding) {
446 /* Overriding the stream encoding implies legacy streams */
447 Py_LegacyWindowsStdioFlag = 1;
448 }
449#endif
450
451done:
452 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
453
454 return res;
455}
456
457
458void
459_Py_ClearStandardStreamEncoding(void)
460{
461 /* Use the same allocator than Py_SetStandardStreamEncoding() */
462 PyMemAllocatorEx old_alloc;
463 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
464
465 /* We won't need them anymore. */
466 if (_Py_StandardStreamEncoding) {
467 PyMem_RawFree(_Py_StandardStreamEncoding);
468 _Py_StandardStreamEncoding = NULL;
469 }
470 if (_Py_StandardStreamErrors) {
471 PyMem_RawFree(_Py_StandardStreamErrors);
472 _Py_StandardStreamErrors = NULL;
473 }
474
475 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
476}
477
478
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100479/* --- Py_GetArgcArgv() ------------------------------------------- */
480
481/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200482static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100483
484
485void
486_Py_ClearArgcArgv(void)
487{
488 PyMemAllocatorEx old_alloc;
489 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
490
Victor Stinner331a6a52019-05-27 16:39:22 +0200491 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100492
493 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
494}
495
496
Victor Stinner4fffd382019-03-06 01:44:31 +0100497static int
Victor Stinner74f65682019-03-15 15:08:05 +0100498_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100499{
Victor Stinner331a6a52019-05-27 16:39:22 +0200500 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100501 int res;
502
503 PyMemAllocatorEx old_alloc;
504 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
505
Victor Stinner331a6a52019-05-27 16:39:22 +0200506 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100507
508 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
509 return res;
510}
511
512
513/* Make the *original* argc/argv available to other modules.
514 This is rare, but it is needed by the secureware extension. */
515void
516Py_GetArgcArgv(int *argc, wchar_t ***argv)
517{
Victor Stinner74f65682019-03-15 15:08:05 +0100518 *argc = (int)orig_argv.length;
519 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100520}
521
522
Victor Stinner331a6a52019-05-27 16:39:22 +0200523/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100524
525#define DECODE_LOCALE_ERR(NAME, LEN) \
526 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200527 ? _PyStatus_ERR("cannot decode " NAME) \
528 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100529
Victor Stinner6c785c02018-08-01 17:56:14 +0200530/* Free memory allocated in config, but don't clear all attributes */
531void
Victor Stinner331a6a52019-05-27 16:39:22 +0200532PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200533{
534#define CLEAR(ATTR) \
535 do { \
536 PyMem_RawFree(ATTR); \
537 ATTR = NULL; \
538 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200539
540 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200541 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200542 CLEAR(config->home);
543 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200544
Victor Stinner331a6a52019-05-27 16:39:22 +0200545 _PyWideStringList_Clear(&config->argv);
546 _PyWideStringList_Clear(&config->warnoptions);
547 _PyWideStringList_Clear(&config->xoptions);
548 _PyWideStringList_Clear(&config->module_search_paths);
549 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200550
551 CLEAR(config->executable);
Steve Dower323e7432019-06-29 14:28:59 -0700552 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200553 CLEAR(config->prefix);
554 CLEAR(config->base_prefix);
555 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200556 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200557
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200558 CLEAR(config->filesystem_encoding);
559 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200560 CLEAR(config->stdio_encoding);
561 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100562 CLEAR(config->run_command);
563 CLEAR(config->run_module);
564 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400565 CLEAR(config->check_hash_pycs_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200566#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200567}
568
569
Victor Stinnercab5d072019-05-17 19:01:14 +0200570void
Victor Stinner331a6a52019-05-27 16:39:22 +0200571_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200572{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200573 memset(config, 0, sizeof(*config));
574
575 config->_config_version = _Py_CONFIG_VERSION;
Victor Stinner022be022019-05-22 23:58:50 +0200576 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200577 config->isolated = -1;
578 config->use_environment = -1;
579 config->dev_mode = -1;
580 config->install_signal_handlers = 1;
581 config->use_hash_seed = -1;
582 config->faulthandler = -1;
583 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200584 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200585 config->parse_argv = 0;
586 config->site_import = -1;
587 config->bytes_warning = -1;
588 config->inspect = -1;
589 config->interactive = -1;
590 config->optimization_level = -1;
591 config->parser_debug= -1;
592 config->write_bytecode = -1;
593 config->verbose = -1;
594 config->quiet = -1;
595 config->user_site_directory = -1;
596 config->configure_c_stdio = 0;
597 config->buffered_stdio = -1;
598 config->_install_importlib = 1;
599 config->check_hash_pycs_mode = NULL;
600 config->pathconfig_warnings = -1;
601 config->_init_main = 1;
602#ifdef MS_WINDOWS
603 config->legacy_windows_stdio = -1;
604#endif
605}
606
607
608static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200609config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200610{
Victor Stinner331a6a52019-05-27 16:39:22 +0200611 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200612
613 config->isolated = 0;
614 config->use_environment = 1;
615 config->site_import = 1;
616 config->bytes_warning = 0;
617 config->inspect = 0;
618 config->interactive = 0;
619 config->optimization_level = 0;
620 config->parser_debug= 0;
621 config->write_bytecode = 1;
622 config->verbose = 0;
623 config->quiet = 0;
624 config->user_site_directory = 1;
625 config->buffered_stdio = 1;
626 config->pathconfig_warnings = 1;
627#ifdef MS_WINDOWS
628 config->legacy_windows_stdio = 0;
629#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200630}
631
632
Victor Stinner331a6a52019-05-27 16:39:22 +0200633PyStatus
634PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200635{
Victor Stinner331a6a52019-05-27 16:39:22 +0200636 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200637
Victor Stinner022be022019-05-22 23:58:50 +0200638 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200639 config->configure_c_stdio = 1;
640 config->parse_argv = 1;
641
Victor Stinner331a6a52019-05-27 16:39:22 +0200642 return _PyStatus_OK();
Victor Stinnercab5d072019-05-17 19:01:14 +0200643}
644
645
Victor Stinner331a6a52019-05-27 16:39:22 +0200646PyStatus
647PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200648{
Victor Stinner331a6a52019-05-27 16:39:22 +0200649 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200650
Victor Stinner022be022019-05-22 23:58:50 +0200651 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200652 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200653 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200654 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200655 config->dev_mode = 0;
656 config->install_signal_handlers = 0;
657 config->use_hash_seed = 0;
658 config->faulthandler = 0;
659 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200660 config->pathconfig_warnings = 0;
661#ifdef MS_WINDOWS
662 config->legacy_windows_stdio = 0;
663#endif
664
Victor Stinner331a6a52019-05-27 16:39:22 +0200665 return _PyStatus_OK();
Victor Stinnercab5d072019-05-17 19:01:14 +0200666}
667
668
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200669/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200670PyStatus
671PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200672{
Victor Stinner331a6a52019-05-27 16:39:22 +0200673 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
674 if (_PyStatus_EXCEPTION(status)) {
675 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200676 }
677
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200678 wchar_t *str2;
679 if (str != NULL) {
680 str2 = _PyMem_RawWcsdup(str);
681 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200682 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200683 }
684 }
685 else {
686 str2 = NULL;
687 }
688 PyMem_RawFree(*config_str);
689 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200690 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200691}
692
693
Victor Stinner331a6a52019-05-27 16:39:22 +0200694static PyStatus
695config_set_bytes_string(PyConfig *config, wchar_t **config_str,
696 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200697{
Victor Stinner331a6a52019-05-27 16:39:22 +0200698 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
699 if (_PyStatus_EXCEPTION(status)) {
700 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400701 }
702
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200703 wchar_t *str2;
704 if (str != NULL) {
705 size_t len;
706 str2 = Py_DecodeLocale(str, &len);
707 if (str2 == NULL) {
708 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200709 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200710 }
711 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200712 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200713 }
714 }
715 }
716 else {
717 str2 = NULL;
718 }
719 PyMem_RawFree(*config_str);
720 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200721 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200722}
723
724
Victor Stinner331a6a52019-05-27 16:39:22 +0200725#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
726 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400727
728
Victor Stinner70005ac2019-05-02 15:25:34 -0400729/* Decode str using Py_DecodeLocale() and set the result into *config_str.
730 Pre-initialize Python if needed to ensure that encodings are properly
731 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200732PyStatus
733PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200734 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400735{
Victor Stinner331a6a52019-05-27 16:39:22 +0200736 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400737}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200738
739
Victor Stinner331a6a52019-05-27 16:39:22 +0200740PyStatus
741_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200742{
Victor Stinner331a6a52019-05-27 16:39:22 +0200743 PyStatus status;
744 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200745
746#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200747#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200748 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200749 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
750 if (_PyStatus_EXCEPTION(status)) { \
751 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200752 } \
753 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100754#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200755 do { \
Miss Islington (bot)96f581c2019-07-01 10:39:58 -0700756 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200757 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200758 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200759 } while (0)
760
Victor Stinner6d1c4672019-05-20 11:02:00 +0200761 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100762 COPY_ATTR(isolated);
763 COPY_ATTR(use_environment);
764 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200765 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200766 COPY_ATTR(use_hash_seed);
767 COPY_ATTR(hash_seed);
768 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200769 COPY_ATTR(faulthandler);
770 COPY_ATTR(tracemalloc);
771 COPY_ATTR(import_time);
772 COPY_ATTR(show_ref_count);
773 COPY_ATTR(show_alloc_count);
774 COPY_ATTR(dump_refs);
775 COPY_ATTR(malloc_stats);
776
Victor Stinner124b9eb2018-08-29 01:29:06 +0200777 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200778 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200779 COPY_WSTR_ATTR(home);
780 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200781
Victor Stinnerae239f62019-05-16 17:02:56 +0200782 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100783 COPY_WSTRLIST(argv);
784 COPY_WSTRLIST(warnoptions);
785 COPY_WSTRLIST(xoptions);
786 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200787 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200788
Victor Stinner124b9eb2018-08-29 01:29:06 +0200789 COPY_WSTR_ATTR(executable);
Steve Dower323e7432019-06-29 14:28:59 -0700790 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200791 COPY_WSTR_ATTR(prefix);
792 COPY_WSTR_ATTR(base_prefix);
793 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200794 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200795
Victor Stinner6c785c02018-08-01 17:56:14 +0200796 COPY_ATTR(site_import);
797 COPY_ATTR(bytes_warning);
798 COPY_ATTR(inspect);
799 COPY_ATTR(interactive);
800 COPY_ATTR(optimization_level);
801 COPY_ATTR(parser_debug);
802 COPY_ATTR(write_bytecode);
803 COPY_ATTR(verbose);
804 COPY_ATTR(quiet);
805 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200806 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200807 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400808 COPY_WSTR_ATTR(filesystem_encoding);
809 COPY_WSTR_ATTR(filesystem_errors);
810 COPY_WSTR_ATTR(stdio_encoding);
811 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200812#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200813 COPY_ATTR(legacy_windows_stdio);
814#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100815 COPY_ATTR(skip_source_first_line);
816 COPY_WSTR_ATTR(run_command);
817 COPY_WSTR_ATTR(run_module);
818 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400819 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200820 COPY_ATTR(pathconfig_warnings);
821 COPY_ATTR(_init_main);
Victor Stinner6c785c02018-08-01 17:56:14 +0200822
823#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200824#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200825#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200826 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200827}
828
829
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100830static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200831config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100832{
833 PyObject *dict;
834
835 dict = PyDict_New();
836 if (dict == NULL) {
837 return NULL;
838 }
839
840#define SET_ITEM(KEY, EXPR) \
841 do { \
842 PyObject *obj = (EXPR); \
843 if (obj == NULL) { \
844 goto fail; \
845 } \
846 int res = PyDict_SetItemString(dict, (KEY), obj); \
847 Py_DECREF(obj); \
848 if (res < 0) { \
849 goto fail; \
850 } \
851 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100852#define SET_ITEM_INT(ATTR) \
853 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
854#define SET_ITEM_UINT(ATTR) \
855 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100856#define FROM_WSTRING(STR) \
857 ((STR != NULL) ? \
858 PyUnicode_FromWideChar(STR, -1) \
859 : (Py_INCREF(Py_None), Py_None))
860#define SET_ITEM_WSTR(ATTR) \
861 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
862#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200863 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100864
Victor Stinner6d1c4672019-05-20 11:02:00 +0200865 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100866 SET_ITEM_INT(isolated);
867 SET_ITEM_INT(use_environment);
868 SET_ITEM_INT(dev_mode);
869 SET_ITEM_INT(install_signal_handlers);
870 SET_ITEM_INT(use_hash_seed);
871 SET_ITEM_UINT(hash_seed);
872 SET_ITEM_INT(faulthandler);
873 SET_ITEM_INT(tracemalloc);
874 SET_ITEM_INT(import_time);
875 SET_ITEM_INT(show_ref_count);
876 SET_ITEM_INT(show_alloc_count);
877 SET_ITEM_INT(dump_refs);
878 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400879 SET_ITEM_WSTR(filesystem_encoding);
880 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100881 SET_ITEM_WSTR(pycache_prefix);
882 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200883 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100884 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100885 SET_ITEM_WSTRLIST(xoptions);
886 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200887 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100888 SET_ITEM_WSTR(home);
889 SET_ITEM_WSTRLIST(module_search_paths);
890 SET_ITEM_WSTR(executable);
Steve Dower323e7432019-06-29 14:28:59 -0700891 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100892 SET_ITEM_WSTR(prefix);
893 SET_ITEM_WSTR(base_prefix);
894 SET_ITEM_WSTR(exec_prefix);
895 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100896 SET_ITEM_INT(site_import);
897 SET_ITEM_INT(bytes_warning);
898 SET_ITEM_INT(inspect);
899 SET_ITEM_INT(interactive);
900 SET_ITEM_INT(optimization_level);
901 SET_ITEM_INT(parser_debug);
902 SET_ITEM_INT(write_bytecode);
903 SET_ITEM_INT(verbose);
904 SET_ITEM_INT(quiet);
905 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200906 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100907 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400908 SET_ITEM_WSTR(stdio_encoding);
909 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100910#ifdef MS_WINDOWS
911 SET_ITEM_INT(legacy_windows_stdio);
912#endif
913 SET_ITEM_INT(skip_source_first_line);
914 SET_ITEM_WSTR(run_command);
915 SET_ITEM_WSTR(run_module);
916 SET_ITEM_WSTR(run_filename);
917 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400918 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200919 SET_ITEM_INT(pathconfig_warnings);
920 SET_ITEM_INT(_init_main);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100921
922 return dict;
923
924fail:
925 Py_DECREF(dict);
926 return NULL;
927
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100928#undef FROM_WSTRING
929#undef SET_ITEM
930#undef SET_ITEM_INT
931#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100932#undef SET_ITEM_WSTR
933#undef SET_ITEM_WSTRLIST
934}
935
936
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100937static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200938config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200939{
Victor Stinner20004952019-03-26 02:31:11 +0100940 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200941}
942
943
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100944/* Get a copy of the environment variable as wchar_t*.
945 Return 0 on success, but *dest can be NULL.
946 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200947static PyStatus
948config_get_env_dup(PyConfig *config,
949 wchar_t **dest,
950 wchar_t *wname, char *name,
951 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200952{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200953 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100954 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200955
Victor Stinner20004952019-03-26 02:31:11 +0100956 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200957 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200958 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200959 }
960
961#ifdef MS_WINDOWS
962 const wchar_t *var = _wgetenv(wname);
963 if (!var || var[0] == '\0') {
964 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200965 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200966 }
967
Victor Stinner331a6a52019-05-27 16:39:22 +0200968 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +0200969#else
970 const char *var = getenv(name);
971 if (!var || var[0] == '\0') {
972 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200973 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200974 }
975
Victor Stinner331a6a52019-05-27 16:39:22 +0200976 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +0200977#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200978}
979
980
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200981#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200982 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200983
984
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100985static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200986config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200987{
Victor Stinner022be022019-05-22 23:58:50 +0200988 if (config->_config_init != _PyConfig_INIT_COMPAT) {
989 /* Python and Isolated configuration ignore global variables */
990 return;
991 }
992
Victor Stinner6c785c02018-08-01 17:56:14 +0200993#define COPY_FLAG(ATTR, VALUE) \
994 if (config->ATTR == -1) { \
995 config->ATTR = VALUE; \
996 }
997#define COPY_NOT_FLAG(ATTR, VALUE) \
998 if (config->ATTR == -1) { \
999 config->ATTR = !(VALUE); \
1000 }
1001
Victor Stinner20004952019-03-26 02:31:11 +01001002 COPY_FLAG(isolated, Py_IsolatedFlag);
1003 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001004 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1005 COPY_FLAG(inspect, Py_InspectFlag);
1006 COPY_FLAG(interactive, Py_InteractiveFlag);
1007 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1008 COPY_FLAG(parser_debug, Py_DebugFlag);
1009 COPY_FLAG(verbose, Py_VerboseFlag);
1010 COPY_FLAG(quiet, Py_QuietFlag);
1011#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001012 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1013#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001014 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001015
Victor Stinner6c785c02018-08-01 17:56:14 +02001016 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1017 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1018 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1019 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1020
Victor Stinner6c785c02018-08-01 17:56:14 +02001021#undef COPY_FLAG
1022#undef COPY_NOT_FLAG
1023}
1024
1025
1026/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001027static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001028config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001029{
1030#define COPY_FLAG(ATTR, VAR) \
1031 if (config->ATTR != -1) { \
1032 VAR = config->ATTR; \
1033 }
1034#define COPY_NOT_FLAG(ATTR, VAR) \
1035 if (config->ATTR != -1) { \
1036 VAR = !config->ATTR; \
1037 }
1038
Victor Stinner20004952019-03-26 02:31:11 +01001039 COPY_FLAG(isolated, Py_IsolatedFlag);
1040 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001041 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1042 COPY_FLAG(inspect, Py_InspectFlag);
1043 COPY_FLAG(interactive, Py_InteractiveFlag);
1044 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1045 COPY_FLAG(parser_debug, Py_DebugFlag);
1046 COPY_FLAG(verbose, Py_VerboseFlag);
1047 COPY_FLAG(quiet, Py_QuietFlag);
1048#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001049 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1050#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001051 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001052
Victor Stinner6c785c02018-08-01 17:56:14 +02001053 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1054 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1055 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1056 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1057
Victor Stinner6c785c02018-08-01 17:56:14 +02001058 /* Random or non-zero hash seed */
1059 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1060 config->hash_seed != 0);
1061
1062#undef COPY_FLAG
1063#undef COPY_NOT_FLAG
1064}
1065
1066
1067/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1068 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001069static PyStatus
1070config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001071{
Victor Stinner331a6a52019-05-27 16:39:22 +02001072 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001073
Victor Stinner6c785c02018-08-01 17:56:14 +02001074 /* If Py_SetProgramName() was called, use its value */
1075 const wchar_t *program_name = _Py_path_config.program_name;
1076 if (program_name != NULL) {
1077 config->program_name = _PyMem_RawWcsdup(program_name);
1078 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001079 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001080 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001081 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001082 }
1083
1084#ifdef __APPLE__
1085 /* On MacOS X, when the Python interpreter is embedded in an
1086 application bundle, it gets executed by a bootstrapping script
1087 that does os.execve() with an argv[0] that's different from the
1088 actual Python executable. This is needed to keep the Finder happy,
1089 or rather, to work around Apple's overly strict requirements of
1090 the process name. However, we still need a usable sys.executable,
1091 so the actual executable path is passed in an environment variable.
1092 See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
1093 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001094 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001095 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001096 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1097 "PYTHONEXECUTABLE environment variable");
1098 if (_PyStatus_EXCEPTION(status)) {
1099 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001100 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001101 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001102 }
1103#ifdef WITH_NEXT_FRAMEWORK
1104 else {
1105 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1106 if (pyvenv_launcher && *pyvenv_launcher) {
1107 /* Used by Mac/Tools/pythonw.c to forward
1108 * the argv0 of the stub executable
1109 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001110 status = CONFIG_SET_BYTES_STR(config,
1111 &config->program_name,
1112 pyvenv_launcher,
1113 "__PYVENV_LAUNCHER__ environment variable");
1114 if (_PyStatus_EXCEPTION(status)) {
1115 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001116 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001117 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001118 }
1119 }
1120#endif /* WITH_NEXT_FRAMEWORK */
1121#endif /* __APPLE__ */
1122
Victor Stinnerfed02e12019-05-17 11:12:09 +02001123 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001124 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001125 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1126 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1127 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001128 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001129 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001130 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001131 }
1132
Victor Stinnerfed02e12019-05-17 11:12:09 +02001133 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001134#ifdef MS_WINDOWS
1135 const wchar_t *default_program_name = L"python";
1136#else
1137 const wchar_t *default_program_name = L"python3";
1138#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001139 status = PyConfig_SetString(config, &config->program_name,
1140 default_program_name);
1141 if (_PyStatus_EXCEPTION(status)) {
1142 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001143 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001144 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001145}
1146
Victor Stinner331a6a52019-05-27 16:39:22 +02001147static PyStatus
1148config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001149{
1150 assert(config->executable == NULL);
1151
1152 /* If Py_SetProgramFullPath() was called, use its value */
1153 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1154 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001155 PyStatus status = PyConfig_SetString(config,
1156 &config->executable,
1157 program_full_path);
1158 if (_PyStatus_EXCEPTION(status)) {
1159 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001160 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001161 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001162 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001163 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001164}
Victor Stinner6c785c02018-08-01 17:56:14 +02001165
Victor Stinner4fffd382019-03-06 01:44:31 +01001166
Victor Stinner6c785c02018-08-01 17:56:14 +02001167static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001168config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001169{
Victor Stinner74f65682019-03-15 15:08:05 +01001170 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001171}
1172
1173
Victor Stinner331a6a52019-05-27 16:39:22 +02001174static PyStatus
1175config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001176{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001177 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001178
1179 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001180 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001181 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001182 PyStatus status = PyConfig_SetString(config, &config->home, home);
1183 if (_PyStatus_EXCEPTION(status)) {
1184 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001185 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001186 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001187 }
1188
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001189 return CONFIG_GET_ENV_DUP(config, &config->home,
1190 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001191}
1192
1193
Victor Stinner331a6a52019-05-27 16:39:22 +02001194static PyStatus
1195config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001196{
Victor Stinner331a6a52019-05-27 16:39:22 +02001197 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001198
1199 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1200 /* Convert a text seed to a numeric one */
1201 if (seed_text && strcmp(seed_text, "random") != 0) {
1202 const char *endptr = seed_text;
1203 unsigned long seed;
1204 errno = 0;
1205 seed = strtoul(seed_text, (char **)&endptr, 10);
1206 if (*endptr != '\0'
1207 || seed > 4294967295UL
1208 || (errno == ERANGE && seed == ULONG_MAX))
1209 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001210 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001211 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001212 }
1213 /* Use a specific hash */
1214 config->use_hash_seed = 1;
1215 config->hash_seed = seed;
1216 }
1217 else {
1218 /* Use a random hash */
1219 config->use_hash_seed = 0;
1220 config->hash_seed = 0;
1221 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001222 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001223}
1224
1225
Victor Stinner6c785c02018-08-01 17:56:14 +02001226static int
1227config_wstr_to_int(const wchar_t *wstr, int *result)
1228{
1229 const wchar_t *endptr = wstr;
1230 errno = 0;
1231 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1232 if (*endptr != '\0' || errno == ERANGE) {
1233 return -1;
1234 }
1235 if (value < INT_MIN || value > INT_MAX) {
1236 return -1;
1237 }
1238
1239 *result = (int)value;
1240 return 0;
1241}
1242
1243
Victor Stinner331a6a52019-05-27 16:39:22 +02001244static PyStatus
1245config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001246{
Victor Stinner331a6a52019-05-27 16:39:22 +02001247 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001248 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001249
Victor Stinner6c785c02018-08-01 17:56:14 +02001250 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001251 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1252 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1253 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1254 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001255
1256 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001257 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001258 if (dont_write_bytecode) {
1259 config->write_bytecode = 0;
1260 }
1261
1262 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001263 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001264 if (no_user_site_directory) {
1265 config->user_site_directory = 0;
1266 }
1267
1268 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001269 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001270 if (unbuffered_stdio) {
1271 config->buffered_stdio = 0;
1272 }
1273
1274#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001275 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001276 "PYTHONLEGACYWINDOWSSTDIO");
1277#endif
1278
Victor Stinner331a6a52019-05-27 16:39:22 +02001279 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001280 config->dump_refs = 1;
1281 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001282 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001283 config->malloc_stats = 1;
1284 }
1285
Victor Stinner331a6a52019-05-27 16:39:22 +02001286 if (config->pythonpath_env == NULL) {
1287 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1288 L"PYTHONPATH", "PYTHONPATH");
1289 if (_PyStatus_EXCEPTION(status)) {
1290 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001291 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001292 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001293
1294 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001295 status = config_init_hash_seed(config);
1296 if (_PyStatus_EXCEPTION(status)) {
1297 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001298 }
1299 }
1300
Victor Stinner331a6a52019-05-27 16:39:22 +02001301 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001302}
1303
1304
Victor Stinner331a6a52019-05-27 16:39:22 +02001305static PyStatus
1306config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001307{
1308 int nframe;
1309 int valid;
1310
Victor Stinner331a6a52019-05-27 16:39:22 +02001311 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001312 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001313 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001314 valid = (nframe >= 0);
1315 }
1316 else {
1317 valid = 0;
1318 }
1319 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001320 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001321 }
1322 config->tracemalloc = nframe;
1323 }
1324
1325 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1326 if (xoption) {
1327 const wchar_t *sep = wcschr(xoption, L'=');
1328 if (sep) {
1329 if (!config_wstr_to_int(sep + 1, &nframe)) {
1330 valid = (nframe >= 0);
1331 }
1332 else {
1333 valid = 0;
1334 }
1335 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001336 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1337 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001338 }
1339 }
1340 else {
1341 /* -X tracemalloc behaves as -X tracemalloc=1 */
1342 nframe = 1;
1343 }
1344 config->tracemalloc = nframe;
1345 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001346 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001347}
1348
1349
Victor Stinner331a6a52019-05-27 16:39:22 +02001350static PyStatus
1351config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001352{
1353 assert(config->pycache_prefix == NULL);
1354
1355 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1356 if (xoption) {
1357 const wchar_t *sep = wcschr(xoption, L'=');
1358 if (sep && wcslen(sep) > 1) {
1359 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1360 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001361 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001362 }
1363 }
1364 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001365 // PYTHONPYCACHEPREFIX env var ignored
1366 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001367 config->pycache_prefix = NULL;
1368 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001369 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001370 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001371
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001372 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1373 L"PYTHONPYCACHEPREFIX",
1374 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001375}
1376
1377
Victor Stinner331a6a52019-05-27 16:39:22 +02001378static PyStatus
1379config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001380{
1381 /* More complex options configured by env var and -X option */
1382 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001383 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001384 || config_get_xoption(config, L"faulthandler")) {
1385 config->faulthandler = 1;
1386 }
1387 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001388 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001389 || config_get_xoption(config, L"importtime")) {
1390 config->import_time = 1;
1391 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001392
Victor Stinner331a6a52019-05-27 16:39:22 +02001393 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001394 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001395 status = config_init_tracemalloc(config);
1396 if (_PyStatus_EXCEPTION(status)) {
1397 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001398 }
1399 }
1400
1401 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001402 status = config_init_pycache_prefix(config);
1403 if (_PyStatus_EXCEPTION(status)) {
1404 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001405 }
1406 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001407 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001408}
1409
1410
Victor Stinner709d23d2019-05-02 14:56:30 -04001411static const wchar_t *
Victor Stinner331a6a52019-05-27 16:39:22 +02001412config_get_stdio_errors(const PyConfig *config)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001413{
1414#ifndef MS_WINDOWS
1415 const char *loc = setlocale(LC_CTYPE, NULL);
1416 if (loc != NULL) {
1417 /* surrogateescape is the default in the legacy C and POSIX locales */
1418 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001419 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001420 }
1421
1422#ifdef PY_COERCE_C_LOCALE
1423 /* surrogateescape is the default in locale coercion target locales */
1424 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001425 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001426 }
1427#endif
1428 }
1429
Victor Stinner709d23d2019-05-02 14:56:30 -04001430 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001431#else
1432 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001433 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001434#endif
1435}
1436
1437
Victor Stinner331a6a52019-05-27 16:39:22 +02001438static PyStatus
1439config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001440{
1441#ifdef MS_WINDOWS
1442 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001443 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001444 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001445#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001446 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001447#else
1448 const char *encoding = nl_langinfo(CODESET);
1449 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001450 return _PyStatus_ERR("failed to get the locale encoding: "
1451 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001452 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001453 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001454 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001455 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001456 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001457#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001458}
1459
1460
Victor Stinner331a6a52019-05-27 16:39:22 +02001461static PyStatus
1462config_init_stdio_encoding(PyConfig *config,
1463 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001464{
Victor Stinner331a6a52019-05-27 16:39:22 +02001465 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001466
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001467 /* If Py_SetStandardStreamEncoding() have been called, use these
1468 parameters. */
1469 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001470 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1471 _Py_StandardStreamEncoding,
1472 "_Py_StandardStreamEncoding");
1473 if (_PyStatus_EXCEPTION(status)) {
1474 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001475 }
1476 }
1477
1478 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001479 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1480 _Py_StandardStreamErrors,
1481 "_Py_StandardStreamErrors");
1482 if (_PyStatus_EXCEPTION(status)) {
1483 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001484 }
1485 }
1486
1487 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001488 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001489 }
1490
1491 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001492 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001493 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001494 char *pythonioencoding = _PyMem_RawStrdup(opt);
1495 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001496 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001497 }
1498
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001499 char *errors = strchr(pythonioencoding, ':');
1500 if (errors) {
1501 *errors = '\0';
1502 errors++;
1503 if (!errors[0]) {
1504 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001505 }
1506 }
1507
1508 /* Does PYTHONIOENCODING contain an encoding? */
1509 if (pythonioencoding[0]) {
1510 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001511 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1512 pythonioencoding,
1513 "PYTHONIOENCODING environment variable");
1514 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001515 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001516 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001517 }
1518 }
1519
1520 /* If the encoding is set but not the error handler,
1521 use "strict" error handler by default.
1522 PYTHONIOENCODING=latin1 behaves as
1523 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001524 if (!errors) {
1525 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001526 }
1527 }
1528
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001529 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001530 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1531 errors,
1532 "PYTHONIOENCODING environment variable");
1533 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001534 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001535 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001536 }
1537 }
1538
1539 PyMem_RawFree(pythonioencoding);
1540 }
1541
1542 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001543 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001544 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001545 status = PyConfig_SetString(config, &config->stdio_encoding,
1546 L"utf-8");
1547 if (_PyStatus_EXCEPTION(status)) {
1548 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001549 }
1550 }
1551 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001552 status = PyConfig_SetString(config, &config->stdio_errors,
1553 L"surrogateescape");
1554 if (_PyStatus_EXCEPTION(status)) {
1555 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001556 }
1557 }
1558 }
1559
1560 /* Choose the default error handler based on the current locale. */
1561 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001562 status = config_get_locale_encoding(config, &config->stdio_encoding);
1563 if (_PyStatus_EXCEPTION(status)) {
1564 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001565 }
1566 }
1567 if (config->stdio_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001568 const wchar_t *errors = config_get_stdio_errors(config);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001569 assert(errors != NULL);
1570
Victor Stinner331a6a52019-05-27 16:39:22 +02001571 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1572 if (_PyStatus_EXCEPTION(status)) {
1573 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001574 }
1575 }
1576
Victor Stinner331a6a52019-05-27 16:39:22 +02001577 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001578}
1579
1580
Victor Stinner331a6a52019-05-27 16:39:22 +02001581static PyStatus
1582config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001583{
Victor Stinner331a6a52019-05-27 16:39:22 +02001584 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001585
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001586 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001587#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001588 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001589#else
Victor Stinnere2510952019-05-02 11:28:57 -04001590
1591#ifdef MS_WINDOWS
1592 if (preconfig->legacy_windows_fs_encoding) {
1593 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001594 status = PyConfig_SetString(config, &config->filesystem_encoding,
1595 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001596 }
1597 else
1598#endif
Victor Stinner20004952019-03-26 02:31:11 +01001599 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001600 status = PyConfig_SetString(config, &config->filesystem_encoding,
1601 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001602 }
Victor Stinnere2510952019-05-02 11:28:57 -04001603#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001604 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001605 status = PyConfig_SetString(config, &config->filesystem_encoding,
1606 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001607 }
Victor Stinnere2510952019-05-02 11:28:57 -04001608#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001609 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001610#ifdef MS_WINDOWS
1611 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001612 status = PyConfig_SetString(config, &config->filesystem_encoding,
1613 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001614#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001615 status = config_get_locale_encoding(config,
1616 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001617#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001618 }
Victor Stinnere2510952019-05-02 11:28:57 -04001619#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001620
Victor Stinner331a6a52019-05-27 16:39:22 +02001621 if (_PyStatus_EXCEPTION(status)) {
1622 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001623 }
1624 }
1625
1626 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001627 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001628#ifdef MS_WINDOWS
1629 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001630 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001631 }
1632 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001633 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001634 }
1635#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001636 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001637#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001638 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1639 if (_PyStatus_EXCEPTION(status)) {
1640 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001641 }
1642 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001643 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001644}
1645
1646
Victor Stinner331a6a52019-05-27 16:39:22 +02001647static PyStatus
1648config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001649{
Victor Stinner331a6a52019-05-27 16:39:22 +02001650 PyStatus status;
1651 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001652
Victor Stinner20004952019-03-26 02:31:11 +01001653 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001654 status = config_read_env_vars(config);
1655 if (_PyStatus_EXCEPTION(status)) {
1656 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001657 }
1658 }
1659
1660 /* -X options */
1661 if (config_get_xoption(config, L"showrefcount")) {
1662 config->show_ref_count = 1;
1663 }
1664 if (config_get_xoption(config, L"showalloccount")) {
1665 config->show_alloc_count = 1;
1666 }
1667
Victor Stinner331a6a52019-05-27 16:39:22 +02001668 status = config_read_complex_options(config);
1669 if (_PyStatus_EXCEPTION(status)) {
1670 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001671 }
1672
Victor Stinner6c785c02018-08-01 17:56:14 +02001673 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001674 status = config_init_home(config);
1675 if (_PyStatus_EXCEPTION(status)) {
1676 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001677 }
1678 }
1679
Steve Dower177a41a2018-11-17 20:41:48 -08001680 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001681 status = config_init_executable(config);
1682 if (_PyStatus_EXCEPTION(status)) {
1683 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001684 }
1685 }
1686
Victor Stinner6c785c02018-08-01 17:56:14 +02001687 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001688 status = _PyConfig_InitPathConfig(config);
1689 if (_PyStatus_EXCEPTION(status)) {
1690 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001691 }
1692 }
1693
1694 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001695 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001696 if (config->faulthandler < 0) {
1697 config->faulthandler = 1;
1698 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001699 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001700 if (config->faulthandler < 0) {
1701 config->faulthandler = 0;
1702 }
1703 if (config->tracemalloc < 0) {
1704 config->tracemalloc = 0;
1705 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001706 if (config->use_hash_seed < 0) {
1707 config->use_hash_seed = 0;
1708 config->hash_seed = 0;
1709 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001710
Victor Stinner70fead22018-08-29 13:45:34 +02001711 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001712 status = config_init_fs_encoding(config, preconfig);
1713 if (_PyStatus_EXCEPTION(status)) {
1714 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001715 }
1716 }
1717
Victor Stinner331a6a52019-05-27 16:39:22 +02001718 status = config_init_stdio_encoding(config, preconfig);
1719 if (_PyStatus_EXCEPTION(status)) {
1720 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001721 }
1722
Victor Stinner62599762019-03-15 16:03:23 +01001723 if (config->argv.length < 1) {
1724 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001725 status = PyWideStringList_Append(&config->argv, L"");
1726 if (_PyStatus_EXCEPTION(status)) {
1727 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001728 }
1729 }
Victor Stinner870b0352019-05-17 03:15:12 +02001730
1731 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001732 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1733 L"default");
1734 if (_PyStatus_EXCEPTION(status)) {
1735 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001736 }
1737 }
1738
1739 if (config->configure_c_stdio < 0) {
1740 config->configure_c_stdio = 1;
1741 }
1742
Victor Stinner331a6a52019-05-27 16:39:22 +02001743 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001744}
Victor Stinner5ed69952018-11-06 15:59:52 +01001745
1746
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001747static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001748config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001749{
1750#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1751 /* don't translate newlines (\r\n <=> \n) */
1752 _setmode(fileno(stdin), O_BINARY);
1753 _setmode(fileno(stdout), O_BINARY);
1754 _setmode(fileno(stderr), O_BINARY);
1755#endif
1756
1757 if (!config->buffered_stdio) {
1758#ifdef HAVE_SETVBUF
1759 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1760 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1761 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1762#else /* !HAVE_SETVBUF */
1763 setbuf(stdin, (char *)NULL);
1764 setbuf(stdout, (char *)NULL);
1765 setbuf(stderr, (char *)NULL);
1766#endif /* !HAVE_SETVBUF */
1767 }
1768 else if (config->interactive) {
1769#ifdef MS_WINDOWS
1770 /* Doesn't have to have line-buffered -- use unbuffered */
1771 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1772 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1773#else /* !MS_WINDOWS */
1774#ifdef HAVE_SETVBUF
1775 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1776 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1777#endif /* HAVE_SETVBUF */
1778#endif /* !MS_WINDOWS */
1779 /* Leave stderr alone - it should be unbuffered anyway. */
1780 }
1781}
1782
1783
1784/* Write the configuration:
1785
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001786 - set Py_xxx global configuration variables
1787 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001788void
Victor Stinner331a6a52019-05-27 16:39:22 +02001789_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001790{
Victor Stinner331a6a52019-05-27 16:39:22 +02001791 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001792
1793 if (config->configure_c_stdio) {
1794 config_init_stdio(config);
1795 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001796
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001797 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001798 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001799 preconfig->isolated = config->isolated;
1800 preconfig->use_environment = config->use_environment;
1801 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001802}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001803
1804
Victor Stinner331a6a52019-05-27 16:39:22 +02001805/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001806
1807static void
Victor Stinner2f549082019-03-29 15:13:46 +01001808config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001809{
Victor Stinner2f549082019-03-29 15:13:46 +01001810 FILE *f = error ? stderr : stdout;
1811
1812 fprintf(f, usage_line, program);
1813 if (error)
1814 fprintf(f, "Try `python -h' for more information.\n");
1815 else {
1816 fputs(usage_1, f);
1817 fputs(usage_2, f);
1818 fputs(usage_3, f);
1819 fprintf(f, usage_4, (wint_t)DELIM);
1820 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1821 fputs(usage_6, f);
1822 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001823}
1824
1825
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001826/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001827static PyStatus
1828config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001829 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001830{
Victor Stinner331a6a52019-05-27 16:39:22 +02001831 PyStatus status;
1832 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001833 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001834 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001835
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001836 _PyOS_ResetGetOpt();
1837 do {
1838 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001839 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001840 if (c == EOF) {
1841 break;
1842 }
1843
1844 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001845 if (config->run_command == NULL) {
1846 /* -c is the last option; following arguments
1847 that look like options are left for the
1848 command to interpret. */
1849 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1850 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1851 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001852 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001853 }
1854 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1855 command[len - 2] = '\n';
1856 command[len - 1] = 0;
1857 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001858 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001859 break;
1860 }
1861
1862 if (c == 'm') {
1863 /* -m is the last option; following arguments
1864 that look like options are left for the
1865 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001866 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001867 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1868 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001869 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001870 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001871 }
1872 break;
1873 }
1874
1875 switch (c) {
1876 case 0:
1877 // Handle long option.
1878 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001879 if (wcscmp(_PyOS_optarg, L"always") == 0
1880 || wcscmp(_PyOS_optarg, L"never") == 0
1881 || wcscmp(_PyOS_optarg, L"default") == 0)
1882 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001883 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1884 _PyOS_optarg);
1885 if (_PyStatus_EXCEPTION(status)) {
1886 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001887 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001888 } else {
1889 fprintf(stderr, "--check-hash-based-pycs must be one of "
1890 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001891 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001892 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001893 }
1894 break;
1895
1896 case 'b':
1897 config->bytes_warning++;
1898 break;
1899
1900 case 'd':
1901 config->parser_debug++;
1902 break;
1903
1904 case 'i':
1905 config->inspect++;
1906 config->interactive++;
1907 break;
1908
Victor Stinner6dcb5422019-03-05 02:44:12 +01001909 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001910 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001911 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001912 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001913 break;
1914
1915 /* case 'J': reserved for Jython */
1916
1917 case 'O':
1918 config->optimization_level++;
1919 break;
1920
1921 case 'B':
1922 config->write_bytecode = 0;
1923 break;
1924
1925 case 's':
1926 config->user_site_directory = 0;
1927 break;
1928
1929 case 'S':
1930 config->site_import = 0;
1931 break;
1932
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001933 case 't':
1934 /* ignored for backwards compatibility */
1935 break;
1936
1937 case 'u':
1938 config->buffered_stdio = 0;
1939 break;
1940
1941 case 'v':
1942 config->verbose++;
1943 break;
1944
1945 case 'x':
1946 config->skip_source_first_line = 1;
1947 break;
1948
1949 case 'h':
1950 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001951 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001952 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001953
1954 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01001955 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001956 break;
1957
1958 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02001959 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
1960 if (_PyStatus_EXCEPTION(status)) {
1961 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001962 }
1963 break;
1964
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001965 case 'q':
1966 config->quiet++;
1967 break;
1968
1969 case 'R':
1970 config->use_hash_seed = 0;
1971 break;
1972
1973 /* This space reserved for other options */
1974
1975 default:
1976 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02001977 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001978 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001979 }
1980 } while (1);
1981
Victor Stinner2f549082019-03-29 15:13:46 +01001982 if (print_version) {
1983 printf("Python %s\n",
1984 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02001985 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01001986 }
1987
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001988 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01001989 && _PyOS_optind < argv->length
1990 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01001991 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001992 {
Victor Stinnerfa153762019-03-20 04:25:38 +01001993 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001994 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001995 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001996 }
1997 }
1998
1999 if (config->run_command != NULL || config->run_module != NULL) {
2000 /* Backup _PyOS_optind */
2001 _PyOS_optind--;
2002 }
2003
Victor Stinnerae239f62019-05-16 17:02:56 +02002004 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002005
Victor Stinner331a6a52019-05-27 16:39:22 +02002006 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002007}
2008
2009
2010#ifdef MS_WINDOWS
2011# define WCSTOK wcstok_s
2012#else
2013# define WCSTOK wcstok
2014#endif
2015
2016/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002017static PyStatus
2018config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002019{
Victor Stinner331a6a52019-05-27 16:39:22 +02002020 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002021 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2022 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002023 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002024 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002025 if (_PyStatus_EXCEPTION(status)) {
2026 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002027 }
2028
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002029 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002030 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002031 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002032 }
2033
2034
2035 wchar_t *warning, *context = NULL;
2036 for (warning = WCSTOK(env, L",", &context);
2037 warning != NULL;
2038 warning = WCSTOK(NULL, L",", &context))
2039 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002040 status = PyWideStringList_Append(warnoptions, warning);
2041 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002042 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002043 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002044 }
2045 }
2046 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002047 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002048}
2049
2050
Victor Stinner331a6a52019-05-27 16:39:22 +02002051static PyStatus
2052config_add_warnoption(PyConfig *config, const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002053{
Victor Stinner331a6a52019-05-27 16:39:22 +02002054 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002055 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002056 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002057 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002058 return PyWideStringList_Append(&config->warnoptions, option);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002059}
2060
2061
Victor Stinner331a6a52019-05-27 16:39:22 +02002062static PyStatus
2063config_init_warnoptions(PyConfig *config,
2064 const PyWideStringList *cmdline_warnoptions,
2065 const PyWideStringList *env_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002066{
Victor Stinner331a6a52019-05-27 16:39:22 +02002067 PyStatus status;
2068
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002069 /* The priority order for warnings configuration is (highest precedence
2070 * first):
2071 *
Victor Stinneraf84a882019-08-23 21:16:51 +02002072 * - early PySys_AddWarnOption() calls
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002073 * - the BytesWarning filter, if needed ('-b', '-bb')
2074 * - any '-W' command line options; then
2075 * - the 'PYTHONWARNINGS' environment variable; then
2076 * - the dev mode filter ('-X dev', 'PYTHONDEVMODE'); then
2077 * - any implicit filters added by _warnings.c/warnings.py
2078 *
2079 * All settings except the last are passed to the warnings module via
2080 * the `sys.warnoptions` list. Since the warnings module works on the basis
2081 * of "the most recently added filter will be checked first", we add
2082 * the lowest precedence entries first so that later entries override them.
2083 */
2084
Victor Stinner20004952019-03-26 02:31:11 +01002085 if (config->dev_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002086 status = config_add_warnoption(config, L"default");
2087 if (_PyStatus_EXCEPTION(status)) {
2088 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002089 }
2090 }
2091
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002092 Py_ssize_t i;
Victor Stinner331a6a52019-05-27 16:39:22 +02002093 const PyWideStringList *options;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002094
Victor Stinner2f549082019-03-29 15:13:46 +01002095 options = env_warnoptions;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002096 for (i = 0; i < options->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002097 status = config_add_warnoption(config, options->items[i]);
2098 if (_PyStatus_EXCEPTION(status)) {
2099 return status;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002100 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002101 }
2102
Victor Stinner2f549082019-03-29 15:13:46 +01002103 options = cmdline_warnoptions;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002104 for (i = 0; i < options->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002105 status = config_add_warnoption(config, options->items[i]);
2106 if (_PyStatus_EXCEPTION(status)) {
2107 return status;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002108 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002109 }
2110
2111 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2112 * don't even try to emit a warning, so we skip setting the filter in that
2113 * case.
2114 */
2115 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002116 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002117 if (config->bytes_warning> 1) {
2118 filter = L"error::BytesWarning";
2119 }
2120 else {
2121 filter = L"default::BytesWarning";
2122 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002123 status = config_add_warnoption(config, filter);
2124 if (_PyStatus_EXCEPTION(status)) {
2125 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002126 }
2127 }
Victor Stinneraf84a882019-08-23 21:16:51 +02002128
2129 /* Handle early PySys_AddWarnOption() calls */
2130 status = _PySys_ReadPreinitWarnOptions(config);
2131 if (_PyStatus_EXCEPTION(status)) {
2132 return status;
2133 }
2134
Victor Stinner331a6a52019-05-27 16:39:22 +02002135 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002136}
2137
2138
Victor Stinner331a6a52019-05-27 16:39:22 +02002139static PyStatus
2140config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002141{
Victor Stinner331a6a52019-05-27 16:39:22 +02002142 const PyWideStringList *cmdline_argv = &config->argv;
2143 PyWideStringList config_argv = PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002144
Victor Stinner74f65682019-03-15 15:08:05 +01002145 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002146 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002147 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002148 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2149 if (_PyStatus_EXCEPTION(status)) {
2150 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002151 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002152 }
2153 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002154 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002155 slice.length = cmdline_argv->length - opt_index;
2156 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002157 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2158 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002159 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002160 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002161 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002162
2163 wchar_t *arg0 = NULL;
2164 if (config->run_command != NULL) {
2165 /* Force sys.argv[0] = '-c' */
2166 arg0 = L"-c";
2167 }
2168 else if (config->run_module != NULL) {
2169 /* Force sys.argv[0] = '-m'*/
2170 arg0 = L"-m";
2171 }
2172 if (arg0 != NULL) {
2173 arg0 = _PyMem_RawWcsdup(arg0);
2174 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002175 _PyWideStringList_Clear(&config_argv);
2176 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002177 }
2178
Victor Stinnerfa153762019-03-20 04:25:38 +01002179 PyMem_RawFree(config_argv.items[0]);
2180 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002181 }
2182
Victor Stinner331a6a52019-05-27 16:39:22 +02002183 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002184 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002185 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002186}
2187
2188
Victor Stinner331a6a52019-05-27 16:39:22 +02002189static PyStatus
2190core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002191{
Victor Stinner331a6a52019-05-27 16:39:22 +02002192 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002193
Victor Stinnercab5d072019-05-17 19:01:14 +02002194 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002195 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2196 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002197 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002198 }
2199
Victor Stinner331a6a52019-05-27 16:39:22 +02002200 PyPreConfig preconfig;
Victor Stinner6d1c4672019-05-20 11:02:00 +02002201 _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002202
Victor Stinner331a6a52019-05-27 16:39:22 +02002203 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002204
Victor Stinner331a6a52019-05-27 16:39:22 +02002205 status = _PyPreCmdline_Read(precmdline, &preconfig);
2206 if (_PyStatus_EXCEPTION(status)) {
2207 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002208 }
2209
Victor Stinner331a6a52019-05-27 16:39:22 +02002210 status = _PyPreCmdline_SetConfig(precmdline, config);
2211 if (_PyStatus_EXCEPTION(status)) {
2212 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002213 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002214 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002215}
2216
2217
Victor Stinner331a6a52019-05-27 16:39:22 +02002218static PyStatus
2219config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002220{
Victor Stinner331a6a52019-05-27 16:39:22 +02002221 PyStatus status;
2222 PyWideStringList cmdline_warnoptions = PyWideStringList_INIT;
2223 PyWideStringList env_warnoptions = PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002224
Victor Stinnerae239f62019-05-16 17:02:56 +02002225 if (config->parse_argv < 0) {
2226 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002227 }
Victor Stinner870b0352019-05-17 03:15:12 +02002228
Victor Stinnerfed02e12019-05-17 11:12:09 +02002229 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002230 status = config_init_program_name(config);
2231 if (_PyStatus_EXCEPTION(status)) {
2232 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002233 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002234 }
Victor Stinner2f549082019-03-29 15:13:46 +01002235
Victor Stinnerae239f62019-05-16 17:02:56 +02002236 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002237 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002238 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2239 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002240 goto done;
2241 }
2242
Victor Stinner331a6a52019-05-27 16:39:22 +02002243 status = config_update_argv(config, opt_index);
2244 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002245 goto done;
2246 }
Victor Stinner2f549082019-03-29 15:13:46 +01002247 }
2248
Victor Stinner2f549082019-03-29 15:13:46 +01002249 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002250 status = config_init_env_warnoptions(config, &env_warnoptions);
2251 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002252 goto done;
2253 }
2254 }
2255
Victor Stinner331a6a52019-05-27 16:39:22 +02002256 status = config_init_warnoptions(config,
Victor Stinneraf84a882019-08-23 21:16:51 +02002257 &cmdline_warnoptions,
2258 &env_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002259 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002260 goto done;
2261 }
2262
Victor Stinner331a6a52019-05-27 16:39:22 +02002263 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002264
2265done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002266 _PyWideStringList_Clear(&cmdline_warnoptions);
2267 _PyWideStringList_Clear(&env_warnoptions);
2268 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002269}
2270
2271
Victor Stinner331a6a52019-05-27 16:39:22 +02002272PyStatus
2273_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002274{
Victor Stinner331a6a52019-05-27 16:39:22 +02002275 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2276 if (_PyStatus_EXCEPTION(status)) {
2277 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002278 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002279
Victor Stinner5f38b842019-05-01 02:30:12 +02002280 return _PyArgv_AsWstrList(args, &config->argv);
2281}
2282
2283
Victor Stinner70005ac2019-05-02 15:25:34 -04002284/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2285 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002286PyStatus
2287PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002288{
2289 _PyArgv args = {
2290 .argc = argc,
2291 .use_bytes_argv = 1,
2292 .bytes_argv = argv,
2293 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002294 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002295}
2296
2297
Victor Stinner331a6a52019-05-27 16:39:22 +02002298PyStatus
2299PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002300{
2301 _PyArgv args = {
2302 .argc = argc,
2303 .use_bytes_argv = 0,
2304 .bytes_argv = NULL,
2305 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002306 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002307}
2308
2309
Miss Islington (bot)96f581c2019-07-01 10:39:58 -07002310PyStatus
2311PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2312 Py_ssize_t length, wchar_t **items)
2313{
2314 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2315 if (_PyStatus_EXCEPTION(status)) {
2316 return status;
2317 }
2318
2319 PyWideStringList list2 = {.length = length, .items = items};
2320 if (_PyWideStringList_Copy(list, &list2) < 0) {
2321 return _PyStatus_NO_MEMORY();
2322 }
2323 return _PyStatus_OK();
2324}
2325
2326
Victor Stinner331a6a52019-05-27 16:39:22 +02002327/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002328
2329 * Command line arguments
2330 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002331 * Py_xxx global configuration variables
2332
2333 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002334PyStatus
2335PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002336{
Victor Stinner331a6a52019-05-27 16:39:22 +02002337 PyStatus status;
2338 PyWideStringList orig_argv = PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002339
Victor Stinner331a6a52019-05-27 16:39:22 +02002340 status = _Py_PreInitializeFromConfig(config, NULL);
2341 if (_PyStatus_EXCEPTION(status)) {
2342 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002343 }
2344
Victor Stinner331a6a52019-05-27 16:39:22 +02002345 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002346
Victor Stinner331a6a52019-05-27 16:39:22 +02002347 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2348 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002349 }
2350
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002351 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002352 status = core_read_precmdline(config, &precmdline);
2353 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002354 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002355 }
2356
Victor Stinner870b0352019-05-17 03:15:12 +02002357 assert(config->isolated >= 0);
2358 if (config->isolated) {
2359 config->use_environment = 0;
2360 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002361 }
2362
Victor Stinner331a6a52019-05-27 16:39:22 +02002363 status = config_read_cmdline(config);
2364 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002365 goto done;
2366 }
2367
Victor Stinneraf84a882019-08-23 21:16:51 +02002368 /* Handle early PySys_AddXOption() calls */
2369 status = _PySys_ReadPreinitXOptions(config);
2370 if (_PyStatus_EXCEPTION(status)) {
2371 goto done;
2372 }
2373
Victor Stinner331a6a52019-05-27 16:39:22 +02002374 status = config_read(config);
2375 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002376 goto done;
2377 }
2378
Victor Stinnercab5d072019-05-17 19:01:14 +02002379 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002380 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002381 goto done;
2382 }
2383
2384 /* Check config consistency */
2385 assert(config->isolated >= 0);
2386 assert(config->use_environment >= 0);
2387 assert(config->dev_mode >= 0);
2388 assert(config->install_signal_handlers >= 0);
2389 assert(config->use_hash_seed >= 0);
2390 assert(config->faulthandler >= 0);
2391 assert(config->tracemalloc >= 0);
2392 assert(config->site_import >= 0);
2393 assert(config->bytes_warning >= 0);
2394 assert(config->inspect >= 0);
2395 assert(config->interactive >= 0);
2396 assert(config->optimization_level >= 0);
2397 assert(config->parser_debug >= 0);
2398 assert(config->write_bytecode >= 0);
2399 assert(config->verbose >= 0);
2400 assert(config->quiet >= 0);
2401 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002402 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002403 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002404 assert(config->buffered_stdio >= 0);
2405 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002406 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002407 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2408 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002409 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2410 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2411 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002412 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002413 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002414 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002415 assert(config->executable != NULL);
Steve Dower323e7432019-06-29 14:28:59 -07002416 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002417 assert(config->prefix != NULL);
2418 assert(config->base_prefix != NULL);
2419 assert(config->exec_prefix != NULL);
2420 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002421 }
2422 assert(config->filesystem_encoding != NULL);
2423 assert(config->filesystem_errors != NULL);
2424 assert(config->stdio_encoding != NULL);
2425 assert(config->stdio_errors != NULL);
2426#ifdef MS_WINDOWS
2427 assert(config->legacy_windows_stdio >= 0);
2428#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002429 /* -c and -m options are exclusive */
2430 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002431 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002432 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002433 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002434
Victor Stinner331a6a52019-05-27 16:39:22 +02002435 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002436
2437done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002438 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002439 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002440 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002441}
Victor Stinner1075d162019-03-25 23:19:57 +01002442
2443
2444PyObject*
2445_Py_GetConfigsAsDict(void)
2446{
Victor Stinner331a6a52019-05-27 16:39:22 +02002447 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002448 PyObject *dict = NULL;
2449
Victor Stinner331a6a52019-05-27 16:39:22 +02002450 result = PyDict_New();
2451 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002452 goto error;
2453 }
2454
Victor Stinner331a6a52019-05-27 16:39:22 +02002455 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002456 dict = _Py_GetGlobalVariablesAsDict();
2457 if (dict == NULL) {
2458 goto error;
2459 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002460 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002461 goto error;
2462 }
2463 Py_CLEAR(dict);
2464
2465 /* pre config */
2466 PyInterpreterState *interp = _PyInterpreterState_Get();
Victor Stinner331a6a52019-05-27 16:39:22 +02002467 const PyPreConfig *pre_config = &_PyRuntime.preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002468 dict = _PyPreConfig_AsDict(pre_config);
2469 if (dict == NULL) {
2470 goto error;
2471 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002472 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002473 goto error;
2474 }
2475 Py_CLEAR(dict);
2476
2477 /* core config */
Victor Stinner331a6a52019-05-27 16:39:22 +02002478 const PyConfig *config = &interp->config;
2479 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002480 if (dict == NULL) {
2481 goto error;
2482 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002483 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002484 goto error;
2485 }
2486 Py_CLEAR(dict);
2487
Victor Stinner331a6a52019-05-27 16:39:22 +02002488 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002489
2490error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002491 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002492 Py_XDECREF(dict);
2493 return NULL;
2494}