blob: c44ae6bdfaccb128ab6d80962e08ef5b77d8dc41 [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"
86" to seed the hashes of str, bytes and datetime objects. It can also be\n"
87" set to an integer in the range [0,4294967295] to get hash values with a\n"
88" 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
300PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100301{
Victor Stinner74f65682019-03-15 15:08:05 +0100302 if (list->length == PY_SSIZE_T_MAX) {
303 /* lenght+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200304 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100305 }
306
Victor Stinner74f65682019-03-15 15:08:05 +0100307 wchar_t *item2 = _PyMem_RawWcsdup(item);
308 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200309 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100310 }
Victor Stinner74f65682019-03-15 15:08:05 +0100311
312 size_t size = (list->length + 1) * sizeof(list->items[0]);
313 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
314 if (items2 == NULL) {
315 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200316 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100317 }
318
319 items2[list->length] = item2;
320 list->items = items2;
321 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200322 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100323}
324
325
Victor Stinner331a6a52019-05-27 16:39:22 +0200326PyStatus
327_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100328{
329 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200330 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
331 if (_PyStatus_EXCEPTION(status)) {
332 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100333 }
334 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200335 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100336}
337
338
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100339static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200340_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100341{
342 for (Py_ssize_t i = 0; i < list->length; i++) {
343 if (wcscmp(list->items[i], item) == 0) {
344 return 1;
345 }
346 }
347 return 0;
348}
349
350
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100351PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200352_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100353{
Victor Stinner331a6a52019-05-27 16:39:22 +0200354 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100355
Victor Stinner74f65682019-03-15 15:08:05 +0100356 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100357 if (pylist == NULL) {
358 return NULL;
359 }
360
Victor Stinner74f65682019-03-15 15:08:05 +0100361 for (Py_ssize_t i = 0; i < list->length; i++) {
362 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
363 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100364 Py_DECREF(pylist);
365 return NULL;
366 }
Victor Stinner74f65682019-03-15 15:08:05 +0100367 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100368 }
369 return pylist;
370}
371
372
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100373/* --- Py_SetStandardStreamEncoding() ----------------------------- */
374
Victor Stinner124b9eb2018-08-29 01:29:06 +0200375/* Helper to allow an embedding application to override the normal
376 * mechanism that attempts to figure out an appropriate IO encoding
377 */
378
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200379static char *_Py_StandardStreamEncoding = NULL;
380static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200381
382int
383Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
384{
385 if (Py_IsInitialized()) {
386 /* This is too late to have any effect */
387 return -1;
388 }
389
390 int res = 0;
391
392 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
393 but Py_Initialize() can change the allocator. Use a known allocator
394 to be able to release the memory later. */
395 PyMemAllocatorEx old_alloc;
396 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
397
398 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
399 * initialised yet.
400 *
401 * However, the raw memory allocators are initialised appropriately
402 * as C static variables, so _PyMem_RawStrdup is OK even though
403 * Py_Initialize hasn't been called yet.
404 */
405 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200406 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200407 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
408 if (!_Py_StandardStreamEncoding) {
409 res = -2;
410 goto done;
411 }
412 }
413 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200414 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200415 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
416 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200417 PyMem_RawFree(_Py_StandardStreamEncoding);
418 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200419 res = -3;
420 goto done;
421 }
422 }
423#ifdef MS_WINDOWS
424 if (_Py_StandardStreamEncoding) {
425 /* Overriding the stream encoding implies legacy streams */
426 Py_LegacyWindowsStdioFlag = 1;
427 }
428#endif
429
430done:
431 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
432
433 return res;
434}
435
436
437void
438_Py_ClearStandardStreamEncoding(void)
439{
440 /* Use the same allocator than Py_SetStandardStreamEncoding() */
441 PyMemAllocatorEx old_alloc;
442 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
443
444 /* We won't need them anymore. */
445 if (_Py_StandardStreamEncoding) {
446 PyMem_RawFree(_Py_StandardStreamEncoding);
447 _Py_StandardStreamEncoding = NULL;
448 }
449 if (_Py_StandardStreamErrors) {
450 PyMem_RawFree(_Py_StandardStreamErrors);
451 _Py_StandardStreamErrors = NULL;
452 }
453
454 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
455}
456
457
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100458/* --- Py_GetArgcArgv() ------------------------------------------- */
459
460/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200461static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100462
463
464void
465_Py_ClearArgcArgv(void)
466{
467 PyMemAllocatorEx old_alloc;
468 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
469
Victor Stinner331a6a52019-05-27 16:39:22 +0200470 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100471
472 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
473}
474
475
Victor Stinner4fffd382019-03-06 01:44:31 +0100476static int
Victor Stinner74f65682019-03-15 15:08:05 +0100477_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100478{
Victor Stinner331a6a52019-05-27 16:39:22 +0200479 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100480 int res;
481
482 PyMemAllocatorEx old_alloc;
483 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
484
Victor Stinner331a6a52019-05-27 16:39:22 +0200485 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100486
487 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
488 return res;
489}
490
491
492/* Make the *original* argc/argv available to other modules.
493 This is rare, but it is needed by the secureware extension. */
494void
495Py_GetArgcArgv(int *argc, wchar_t ***argv)
496{
Victor Stinner74f65682019-03-15 15:08:05 +0100497 *argc = (int)orig_argv.length;
498 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100499}
500
501
Victor Stinner331a6a52019-05-27 16:39:22 +0200502/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100503
504#define DECODE_LOCALE_ERR(NAME, LEN) \
505 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200506 ? _PyStatus_ERR("cannot decode " NAME) \
507 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100508
Victor Stinner6c785c02018-08-01 17:56:14 +0200509/* Free memory allocated in config, but don't clear all attributes */
510void
Victor Stinner331a6a52019-05-27 16:39:22 +0200511PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200512{
513#define CLEAR(ATTR) \
514 do { \
515 PyMem_RawFree(ATTR); \
516 ATTR = NULL; \
517 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200518
519 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200520 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200521 CLEAR(config->home);
522 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200523
Victor Stinner331a6a52019-05-27 16:39:22 +0200524 _PyWideStringList_Clear(&config->argv);
525 _PyWideStringList_Clear(&config->warnoptions);
526 _PyWideStringList_Clear(&config->xoptions);
527 _PyWideStringList_Clear(&config->module_search_paths);
528 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200529
530 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700531 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200532 CLEAR(config->prefix);
533 CLEAR(config->base_prefix);
534 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200535 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200536
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200537 CLEAR(config->filesystem_encoding);
538 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200539 CLEAR(config->stdio_encoding);
540 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100541 CLEAR(config->run_command);
542 CLEAR(config->run_module);
543 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400544 CLEAR(config->check_hash_pycs_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200545#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200546}
547
548
Victor Stinnercab5d072019-05-17 19:01:14 +0200549void
Victor Stinner331a6a52019-05-27 16:39:22 +0200550_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200551{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200552 memset(config, 0, sizeof(*config));
553
554 config->_config_version = _Py_CONFIG_VERSION;
Victor Stinner022be022019-05-22 23:58:50 +0200555 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200556 config->isolated = -1;
557 config->use_environment = -1;
558 config->dev_mode = -1;
559 config->install_signal_handlers = 1;
560 config->use_hash_seed = -1;
561 config->faulthandler = -1;
562 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200563 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200564 config->parse_argv = 0;
565 config->site_import = -1;
566 config->bytes_warning = -1;
567 config->inspect = -1;
568 config->interactive = -1;
569 config->optimization_level = -1;
570 config->parser_debug= -1;
571 config->write_bytecode = -1;
572 config->verbose = -1;
573 config->quiet = -1;
574 config->user_site_directory = -1;
575 config->configure_c_stdio = 0;
576 config->buffered_stdio = -1;
577 config->_install_importlib = 1;
578 config->check_hash_pycs_mode = NULL;
579 config->pathconfig_warnings = -1;
580 config->_init_main = 1;
581#ifdef MS_WINDOWS
582 config->legacy_windows_stdio = -1;
583#endif
584}
585
586
587static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200588config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200589{
Victor Stinner331a6a52019-05-27 16:39:22 +0200590 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200591
592 config->isolated = 0;
593 config->use_environment = 1;
594 config->site_import = 1;
595 config->bytes_warning = 0;
596 config->inspect = 0;
597 config->interactive = 0;
598 config->optimization_level = 0;
599 config->parser_debug= 0;
600 config->write_bytecode = 1;
601 config->verbose = 0;
602 config->quiet = 0;
603 config->user_site_directory = 1;
604 config->buffered_stdio = 1;
605 config->pathconfig_warnings = 1;
606#ifdef MS_WINDOWS
607 config->legacy_windows_stdio = 0;
608#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200609}
610
611
Victor Stinner331a6a52019-05-27 16:39:22 +0200612PyStatus
613PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200614{
Victor Stinner331a6a52019-05-27 16:39:22 +0200615 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200616
Victor Stinner022be022019-05-22 23:58:50 +0200617 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200618 config->configure_c_stdio = 1;
619 config->parse_argv = 1;
620
Victor Stinner331a6a52019-05-27 16:39:22 +0200621 return _PyStatus_OK();
Victor Stinnercab5d072019-05-17 19:01:14 +0200622}
623
624
Victor Stinner331a6a52019-05-27 16:39:22 +0200625PyStatus
626PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200627{
Victor Stinner331a6a52019-05-27 16:39:22 +0200628 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200629
Victor Stinner022be022019-05-22 23:58:50 +0200630 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200631 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200632 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200633 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200634 config->dev_mode = 0;
635 config->install_signal_handlers = 0;
636 config->use_hash_seed = 0;
637 config->faulthandler = 0;
638 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200639 config->pathconfig_warnings = 0;
640#ifdef MS_WINDOWS
641 config->legacy_windows_stdio = 0;
642#endif
643
Victor Stinner331a6a52019-05-27 16:39:22 +0200644 return _PyStatus_OK();
Victor Stinnercab5d072019-05-17 19:01:14 +0200645}
646
647
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200648/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200649PyStatus
650PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200651{
Victor Stinner331a6a52019-05-27 16:39:22 +0200652 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
653 if (_PyStatus_EXCEPTION(status)) {
654 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200655 }
656
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200657 wchar_t *str2;
658 if (str != NULL) {
659 str2 = _PyMem_RawWcsdup(str);
660 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200661 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200662 }
663 }
664 else {
665 str2 = NULL;
666 }
667 PyMem_RawFree(*config_str);
668 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200669 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200670}
671
672
Victor Stinner331a6a52019-05-27 16:39:22 +0200673static PyStatus
674config_set_bytes_string(PyConfig *config, wchar_t **config_str,
675 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200676{
Victor Stinner331a6a52019-05-27 16:39:22 +0200677 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
678 if (_PyStatus_EXCEPTION(status)) {
679 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400680 }
681
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200682 wchar_t *str2;
683 if (str != NULL) {
684 size_t len;
685 str2 = Py_DecodeLocale(str, &len);
686 if (str2 == NULL) {
687 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200688 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200689 }
690 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200691 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200692 }
693 }
694 }
695 else {
696 str2 = NULL;
697 }
698 PyMem_RawFree(*config_str);
699 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200700 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200701}
702
703
Victor Stinner331a6a52019-05-27 16:39:22 +0200704#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
705 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400706
707
Victor Stinner70005ac2019-05-02 15:25:34 -0400708/* Decode str using Py_DecodeLocale() and set the result into *config_str.
709 Pre-initialize Python if needed to ensure that encodings are properly
710 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200711PyStatus
712PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200713 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400714{
Victor Stinner331a6a52019-05-27 16:39:22 +0200715 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400716}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200717
718
Victor Stinner331a6a52019-05-27 16:39:22 +0200719PyStatus
720_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200721{
Victor Stinner331a6a52019-05-27 16:39:22 +0200722 PyStatus status;
723 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200724
725#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200726#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200727 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200728 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
729 if (_PyStatus_EXCEPTION(status)) { \
730 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200731 } \
732 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100733#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200734 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200735 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200736 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200737 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200738 } while (0)
739
Victor Stinner6d1c4672019-05-20 11:02:00 +0200740 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100741 COPY_ATTR(isolated);
742 COPY_ATTR(use_environment);
743 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200744 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200745 COPY_ATTR(use_hash_seed);
746 COPY_ATTR(hash_seed);
747 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200748 COPY_ATTR(faulthandler);
749 COPY_ATTR(tracemalloc);
750 COPY_ATTR(import_time);
751 COPY_ATTR(show_ref_count);
752 COPY_ATTR(show_alloc_count);
753 COPY_ATTR(dump_refs);
754 COPY_ATTR(malloc_stats);
755
Victor Stinner124b9eb2018-08-29 01:29:06 +0200756 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200757 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200758 COPY_WSTR_ATTR(home);
759 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200760
Victor Stinnerae239f62019-05-16 17:02:56 +0200761 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100762 COPY_WSTRLIST(argv);
763 COPY_WSTRLIST(warnoptions);
764 COPY_WSTRLIST(xoptions);
765 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200766 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200767
Victor Stinner124b9eb2018-08-29 01:29:06 +0200768 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700769 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200770 COPY_WSTR_ATTR(prefix);
771 COPY_WSTR_ATTR(base_prefix);
772 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200773 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200774
Victor Stinner6c785c02018-08-01 17:56:14 +0200775 COPY_ATTR(site_import);
776 COPY_ATTR(bytes_warning);
777 COPY_ATTR(inspect);
778 COPY_ATTR(interactive);
779 COPY_ATTR(optimization_level);
780 COPY_ATTR(parser_debug);
781 COPY_ATTR(write_bytecode);
782 COPY_ATTR(verbose);
783 COPY_ATTR(quiet);
784 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200785 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200786 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400787 COPY_WSTR_ATTR(filesystem_encoding);
788 COPY_WSTR_ATTR(filesystem_errors);
789 COPY_WSTR_ATTR(stdio_encoding);
790 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200791#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200792 COPY_ATTR(legacy_windows_stdio);
793#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100794 COPY_ATTR(skip_source_first_line);
795 COPY_WSTR_ATTR(run_command);
796 COPY_WSTR_ATTR(run_module);
797 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400798 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200799 COPY_ATTR(pathconfig_warnings);
800 COPY_ATTR(_init_main);
Victor Stinner6c785c02018-08-01 17:56:14 +0200801
802#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200803#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200804#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200805 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200806}
807
808
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100809static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200810config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100811{
812 PyObject *dict;
813
814 dict = PyDict_New();
815 if (dict == NULL) {
816 return NULL;
817 }
818
819#define SET_ITEM(KEY, EXPR) \
820 do { \
821 PyObject *obj = (EXPR); \
822 if (obj == NULL) { \
823 goto fail; \
824 } \
825 int res = PyDict_SetItemString(dict, (KEY), obj); \
826 Py_DECREF(obj); \
827 if (res < 0) { \
828 goto fail; \
829 } \
830 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100831#define SET_ITEM_INT(ATTR) \
832 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
833#define SET_ITEM_UINT(ATTR) \
834 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100835#define FROM_WSTRING(STR) \
836 ((STR != NULL) ? \
837 PyUnicode_FromWideChar(STR, -1) \
838 : (Py_INCREF(Py_None), Py_None))
839#define SET_ITEM_WSTR(ATTR) \
840 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
841#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200842 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100843
Victor Stinner6d1c4672019-05-20 11:02:00 +0200844 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100845 SET_ITEM_INT(isolated);
846 SET_ITEM_INT(use_environment);
847 SET_ITEM_INT(dev_mode);
848 SET_ITEM_INT(install_signal_handlers);
849 SET_ITEM_INT(use_hash_seed);
850 SET_ITEM_UINT(hash_seed);
851 SET_ITEM_INT(faulthandler);
852 SET_ITEM_INT(tracemalloc);
853 SET_ITEM_INT(import_time);
854 SET_ITEM_INT(show_ref_count);
855 SET_ITEM_INT(show_alloc_count);
856 SET_ITEM_INT(dump_refs);
857 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400858 SET_ITEM_WSTR(filesystem_encoding);
859 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100860 SET_ITEM_WSTR(pycache_prefix);
861 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200862 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100863 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100864 SET_ITEM_WSTRLIST(xoptions);
865 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200866 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100867 SET_ITEM_WSTR(home);
868 SET_ITEM_WSTRLIST(module_search_paths);
869 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700870 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100871 SET_ITEM_WSTR(prefix);
872 SET_ITEM_WSTR(base_prefix);
873 SET_ITEM_WSTR(exec_prefix);
874 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100875 SET_ITEM_INT(site_import);
876 SET_ITEM_INT(bytes_warning);
877 SET_ITEM_INT(inspect);
878 SET_ITEM_INT(interactive);
879 SET_ITEM_INT(optimization_level);
880 SET_ITEM_INT(parser_debug);
881 SET_ITEM_INT(write_bytecode);
882 SET_ITEM_INT(verbose);
883 SET_ITEM_INT(quiet);
884 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200885 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100886 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400887 SET_ITEM_WSTR(stdio_encoding);
888 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100889#ifdef MS_WINDOWS
890 SET_ITEM_INT(legacy_windows_stdio);
891#endif
892 SET_ITEM_INT(skip_source_first_line);
893 SET_ITEM_WSTR(run_command);
894 SET_ITEM_WSTR(run_module);
895 SET_ITEM_WSTR(run_filename);
896 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400897 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200898 SET_ITEM_INT(pathconfig_warnings);
899 SET_ITEM_INT(_init_main);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100900
901 return dict;
902
903fail:
904 Py_DECREF(dict);
905 return NULL;
906
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100907#undef FROM_WSTRING
908#undef SET_ITEM
909#undef SET_ITEM_INT
910#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100911#undef SET_ITEM_WSTR
912#undef SET_ITEM_WSTRLIST
913}
914
915
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100916static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200917config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200918{
Victor Stinner20004952019-03-26 02:31:11 +0100919 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200920}
921
922
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100923/* Get a copy of the environment variable as wchar_t*.
924 Return 0 on success, but *dest can be NULL.
925 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200926static PyStatus
927config_get_env_dup(PyConfig *config,
928 wchar_t **dest,
929 wchar_t *wname, char *name,
930 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200931{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200932 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100933 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200934
Victor Stinner20004952019-03-26 02:31:11 +0100935 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200936 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200937 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200938 }
939
940#ifdef MS_WINDOWS
941 const wchar_t *var = _wgetenv(wname);
942 if (!var || var[0] == '\0') {
943 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200944 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200945 }
946
Victor Stinner331a6a52019-05-27 16:39:22 +0200947 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +0200948#else
949 const char *var = getenv(name);
950 if (!var || var[0] == '\0') {
951 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200952 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200953 }
954
Victor Stinner331a6a52019-05-27 16:39:22 +0200955 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +0200956#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200957}
958
959
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200960#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200961 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200962
963
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100964static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200965config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200966{
Victor Stinner022be022019-05-22 23:58:50 +0200967 if (config->_config_init != _PyConfig_INIT_COMPAT) {
968 /* Python and Isolated configuration ignore global variables */
969 return;
970 }
971
Victor Stinner6c785c02018-08-01 17:56:14 +0200972#define COPY_FLAG(ATTR, VALUE) \
973 if (config->ATTR == -1) { \
974 config->ATTR = VALUE; \
975 }
976#define COPY_NOT_FLAG(ATTR, VALUE) \
977 if (config->ATTR == -1) { \
978 config->ATTR = !(VALUE); \
979 }
980
Victor Stinner20004952019-03-26 02:31:11 +0100981 COPY_FLAG(isolated, Py_IsolatedFlag);
982 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +0200983 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
984 COPY_FLAG(inspect, Py_InspectFlag);
985 COPY_FLAG(interactive, Py_InteractiveFlag);
986 COPY_FLAG(optimization_level, Py_OptimizeFlag);
987 COPY_FLAG(parser_debug, Py_DebugFlag);
988 COPY_FLAG(verbose, Py_VerboseFlag);
989 COPY_FLAG(quiet, Py_QuietFlag);
990#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200991 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
992#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200993 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +0200994
Victor Stinner6c785c02018-08-01 17:56:14 +0200995 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
996 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
997 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
998 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
999
Victor Stinner6c785c02018-08-01 17:56:14 +02001000#undef COPY_FLAG
1001#undef COPY_NOT_FLAG
1002}
1003
1004
1005/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001006static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001007config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001008{
1009#define COPY_FLAG(ATTR, VAR) \
1010 if (config->ATTR != -1) { \
1011 VAR = config->ATTR; \
1012 }
1013#define COPY_NOT_FLAG(ATTR, VAR) \
1014 if (config->ATTR != -1) { \
1015 VAR = !config->ATTR; \
1016 }
1017
Victor Stinner20004952019-03-26 02:31:11 +01001018 COPY_FLAG(isolated, Py_IsolatedFlag);
1019 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001020 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1021 COPY_FLAG(inspect, Py_InspectFlag);
1022 COPY_FLAG(interactive, Py_InteractiveFlag);
1023 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1024 COPY_FLAG(parser_debug, Py_DebugFlag);
1025 COPY_FLAG(verbose, Py_VerboseFlag);
1026 COPY_FLAG(quiet, Py_QuietFlag);
1027#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001028 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1029#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001030 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001031
Victor Stinner6c785c02018-08-01 17:56:14 +02001032 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1033 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1034 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1035 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1036
Victor Stinner6c785c02018-08-01 17:56:14 +02001037 /* Random or non-zero hash seed */
1038 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1039 config->hash_seed != 0);
1040
1041#undef COPY_FLAG
1042#undef COPY_NOT_FLAG
1043}
1044
1045
1046/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1047 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001048static PyStatus
1049config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001050{
Victor Stinner331a6a52019-05-27 16:39:22 +02001051 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001052
Victor Stinner6c785c02018-08-01 17:56:14 +02001053 /* If Py_SetProgramName() was called, use its value */
1054 const wchar_t *program_name = _Py_path_config.program_name;
1055 if (program_name != NULL) {
1056 config->program_name = _PyMem_RawWcsdup(program_name);
1057 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001058 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001059 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001060 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001061 }
1062
1063#ifdef __APPLE__
1064 /* On MacOS X, when the Python interpreter is embedded in an
1065 application bundle, it gets executed by a bootstrapping script
1066 that does os.execve() with an argv[0] that's different from the
1067 actual Python executable. This is needed to keep the Finder happy,
1068 or rather, to work around Apple's overly strict requirements of
1069 the process name. However, we still need a usable sys.executable,
1070 so the actual executable path is passed in an environment variable.
1071 See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
1072 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001073 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001074 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001075 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1076 "PYTHONEXECUTABLE environment variable");
1077 if (_PyStatus_EXCEPTION(status)) {
1078 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001079 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001080 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001081 }
1082#ifdef WITH_NEXT_FRAMEWORK
1083 else {
1084 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1085 if (pyvenv_launcher && *pyvenv_launcher) {
1086 /* Used by Mac/Tools/pythonw.c to forward
1087 * the argv0 of the stub executable
1088 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001089 status = CONFIG_SET_BYTES_STR(config,
1090 &config->program_name,
1091 pyvenv_launcher,
1092 "__PYVENV_LAUNCHER__ environment variable");
1093 if (_PyStatus_EXCEPTION(status)) {
1094 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001095 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001096 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001097 }
1098 }
1099#endif /* WITH_NEXT_FRAMEWORK */
1100#endif /* __APPLE__ */
1101
Victor Stinnerfed02e12019-05-17 11:12:09 +02001102 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001103 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001104 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1105 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1106 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001107 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001108 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001109 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001110 }
1111
Victor Stinnerfed02e12019-05-17 11:12:09 +02001112 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001113#ifdef MS_WINDOWS
1114 const wchar_t *default_program_name = L"python";
1115#else
1116 const wchar_t *default_program_name = L"python3";
1117#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001118 status = PyConfig_SetString(config, &config->program_name,
1119 default_program_name);
1120 if (_PyStatus_EXCEPTION(status)) {
1121 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001122 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001123 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001124}
1125
Victor Stinner331a6a52019-05-27 16:39:22 +02001126static PyStatus
1127config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001128{
1129 assert(config->executable == NULL);
1130
1131 /* If Py_SetProgramFullPath() was called, use its value */
1132 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1133 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001134 PyStatus status = PyConfig_SetString(config,
1135 &config->executable,
1136 program_full_path);
1137 if (_PyStatus_EXCEPTION(status)) {
1138 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001139 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001140 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001141 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001142 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001143}
Victor Stinner6c785c02018-08-01 17:56:14 +02001144
Victor Stinner4fffd382019-03-06 01:44:31 +01001145
Victor Stinner6c785c02018-08-01 17:56:14 +02001146static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001147config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001148{
Victor Stinner74f65682019-03-15 15:08:05 +01001149 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001150}
1151
1152
Victor Stinner331a6a52019-05-27 16:39:22 +02001153static PyStatus
1154config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001155{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001156 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001157
1158 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001159 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001160 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001161 PyStatus status = PyConfig_SetString(config, &config->home, home);
1162 if (_PyStatus_EXCEPTION(status)) {
1163 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001164 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001165 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001166 }
1167
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001168 return CONFIG_GET_ENV_DUP(config, &config->home,
1169 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001170}
1171
1172
Victor Stinner331a6a52019-05-27 16:39:22 +02001173static PyStatus
1174config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001175{
Victor Stinner331a6a52019-05-27 16:39:22 +02001176 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001177
1178 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1179 /* Convert a text seed to a numeric one */
1180 if (seed_text && strcmp(seed_text, "random") != 0) {
1181 const char *endptr = seed_text;
1182 unsigned long seed;
1183 errno = 0;
1184 seed = strtoul(seed_text, (char **)&endptr, 10);
1185 if (*endptr != '\0'
1186 || seed > 4294967295UL
1187 || (errno == ERANGE && seed == ULONG_MAX))
1188 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001189 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001190 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001191 }
1192 /* Use a specific hash */
1193 config->use_hash_seed = 1;
1194 config->hash_seed = seed;
1195 }
1196 else {
1197 /* Use a random hash */
1198 config->use_hash_seed = 0;
1199 config->hash_seed = 0;
1200 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001201 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001202}
1203
1204
Victor Stinner6c785c02018-08-01 17:56:14 +02001205static int
1206config_wstr_to_int(const wchar_t *wstr, int *result)
1207{
1208 const wchar_t *endptr = wstr;
1209 errno = 0;
1210 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1211 if (*endptr != '\0' || errno == ERANGE) {
1212 return -1;
1213 }
1214 if (value < INT_MIN || value > INT_MAX) {
1215 return -1;
1216 }
1217
1218 *result = (int)value;
1219 return 0;
1220}
1221
1222
Victor Stinner331a6a52019-05-27 16:39:22 +02001223static PyStatus
1224config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001225{
Victor Stinner331a6a52019-05-27 16:39:22 +02001226 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001227 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001228
Victor Stinner6c785c02018-08-01 17:56:14 +02001229 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001230 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1231 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1232 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1233 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001234
1235 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001236 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001237 if (dont_write_bytecode) {
1238 config->write_bytecode = 0;
1239 }
1240
1241 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001242 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001243 if (no_user_site_directory) {
1244 config->user_site_directory = 0;
1245 }
1246
1247 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001248 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001249 if (unbuffered_stdio) {
1250 config->buffered_stdio = 0;
1251 }
1252
1253#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001254 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001255 "PYTHONLEGACYWINDOWSSTDIO");
1256#endif
1257
Victor Stinner331a6a52019-05-27 16:39:22 +02001258 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001259 config->dump_refs = 1;
1260 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001261 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001262 config->malloc_stats = 1;
1263 }
1264
Victor Stinner331a6a52019-05-27 16:39:22 +02001265 if (config->pythonpath_env == NULL) {
1266 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1267 L"PYTHONPATH", "PYTHONPATH");
1268 if (_PyStatus_EXCEPTION(status)) {
1269 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001270 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001271 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001272
1273 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001274 status = config_init_hash_seed(config);
1275 if (_PyStatus_EXCEPTION(status)) {
1276 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001277 }
1278 }
1279
Victor Stinner331a6a52019-05-27 16:39:22 +02001280 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001281}
1282
1283
Victor Stinner331a6a52019-05-27 16:39:22 +02001284static PyStatus
1285config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001286{
1287 int nframe;
1288 int valid;
1289
Victor Stinner331a6a52019-05-27 16:39:22 +02001290 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001291 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001292 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001293 valid = (nframe >= 0);
1294 }
1295 else {
1296 valid = 0;
1297 }
1298 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001299 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001300 }
1301 config->tracemalloc = nframe;
1302 }
1303
1304 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1305 if (xoption) {
1306 const wchar_t *sep = wcschr(xoption, L'=');
1307 if (sep) {
1308 if (!config_wstr_to_int(sep + 1, &nframe)) {
1309 valid = (nframe >= 0);
1310 }
1311 else {
1312 valid = 0;
1313 }
1314 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001315 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1316 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001317 }
1318 }
1319 else {
1320 /* -X tracemalloc behaves as -X tracemalloc=1 */
1321 nframe = 1;
1322 }
1323 config->tracemalloc = nframe;
1324 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001325 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001326}
1327
1328
Victor Stinner331a6a52019-05-27 16:39:22 +02001329static PyStatus
1330config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001331{
1332 assert(config->pycache_prefix == NULL);
1333
1334 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1335 if (xoption) {
1336 const wchar_t *sep = wcschr(xoption, L'=');
1337 if (sep && wcslen(sep) > 1) {
1338 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1339 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001340 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001341 }
1342 }
1343 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001344 // PYTHONPYCACHEPREFIX env var ignored
1345 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001346 config->pycache_prefix = NULL;
1347 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001348 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001349 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001350
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001351 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1352 L"PYTHONPYCACHEPREFIX",
1353 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001354}
1355
1356
Victor Stinner331a6a52019-05-27 16:39:22 +02001357static PyStatus
1358config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001359{
1360 /* More complex options configured by env var and -X option */
1361 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001362 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001363 || config_get_xoption(config, L"faulthandler")) {
1364 config->faulthandler = 1;
1365 }
1366 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001367 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001368 || config_get_xoption(config, L"importtime")) {
1369 config->import_time = 1;
1370 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001371
Victor Stinner331a6a52019-05-27 16:39:22 +02001372 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001373 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001374 status = config_init_tracemalloc(config);
1375 if (_PyStatus_EXCEPTION(status)) {
1376 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001377 }
1378 }
1379
1380 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001381 status = config_init_pycache_prefix(config);
1382 if (_PyStatus_EXCEPTION(status)) {
1383 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001384 }
1385 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001386 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001387}
1388
1389
Victor Stinner709d23d2019-05-02 14:56:30 -04001390static const wchar_t *
Victor Stinner331a6a52019-05-27 16:39:22 +02001391config_get_stdio_errors(const PyConfig *config)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001392{
1393#ifndef MS_WINDOWS
1394 const char *loc = setlocale(LC_CTYPE, NULL);
1395 if (loc != NULL) {
1396 /* surrogateescape is the default in the legacy C and POSIX locales */
1397 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001398 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001399 }
1400
1401#ifdef PY_COERCE_C_LOCALE
1402 /* surrogateescape is the default in locale coercion target locales */
1403 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001404 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001405 }
1406#endif
1407 }
1408
Victor Stinner709d23d2019-05-02 14:56:30 -04001409 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001410#else
1411 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001412 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001413#endif
1414}
1415
1416
Victor Stinner331a6a52019-05-27 16:39:22 +02001417static PyStatus
1418config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001419{
1420#ifdef MS_WINDOWS
1421 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001422 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001423 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001424#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001425 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001426#else
1427 const char *encoding = nl_langinfo(CODESET);
1428 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001429 return _PyStatus_ERR("failed to get the locale encoding: "
1430 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001431 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001432 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001433 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001434 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001435 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001436#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001437}
1438
1439
Victor Stinner331a6a52019-05-27 16:39:22 +02001440static PyStatus
1441config_init_stdio_encoding(PyConfig *config,
1442 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001443{
Victor Stinner331a6a52019-05-27 16:39:22 +02001444 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001445
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001446 /* If Py_SetStandardStreamEncoding() have been called, use these
1447 parameters. */
1448 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001449 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1450 _Py_StandardStreamEncoding,
1451 "_Py_StandardStreamEncoding");
1452 if (_PyStatus_EXCEPTION(status)) {
1453 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001454 }
1455 }
1456
1457 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001458 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1459 _Py_StandardStreamErrors,
1460 "_Py_StandardStreamErrors");
1461 if (_PyStatus_EXCEPTION(status)) {
1462 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001463 }
1464 }
1465
1466 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001467 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001468 }
1469
1470 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001471 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001472 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001473 char *pythonioencoding = _PyMem_RawStrdup(opt);
1474 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001475 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001476 }
1477
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001478 char *errors = strchr(pythonioencoding, ':');
1479 if (errors) {
1480 *errors = '\0';
1481 errors++;
1482 if (!errors[0]) {
1483 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001484 }
1485 }
1486
1487 /* Does PYTHONIOENCODING contain an encoding? */
1488 if (pythonioencoding[0]) {
1489 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001490 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1491 pythonioencoding,
1492 "PYTHONIOENCODING environment variable");
1493 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001494 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001495 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001496 }
1497 }
1498
1499 /* If the encoding is set but not the error handler,
1500 use "strict" error handler by default.
1501 PYTHONIOENCODING=latin1 behaves as
1502 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001503 if (!errors) {
1504 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001505 }
1506 }
1507
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001508 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001509 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1510 errors,
1511 "PYTHONIOENCODING environment variable");
1512 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001513 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001514 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001515 }
1516 }
1517
1518 PyMem_RawFree(pythonioencoding);
1519 }
1520
1521 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001522 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001523 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001524 status = PyConfig_SetString(config, &config->stdio_encoding,
1525 L"utf-8");
1526 if (_PyStatus_EXCEPTION(status)) {
1527 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001528 }
1529 }
1530 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001531 status = PyConfig_SetString(config, &config->stdio_errors,
1532 L"surrogateescape");
1533 if (_PyStatus_EXCEPTION(status)) {
1534 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001535 }
1536 }
1537 }
1538
1539 /* Choose the default error handler based on the current locale. */
1540 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001541 status = config_get_locale_encoding(config, &config->stdio_encoding);
1542 if (_PyStatus_EXCEPTION(status)) {
1543 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001544 }
1545 }
1546 if (config->stdio_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001547 const wchar_t *errors = config_get_stdio_errors(config);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001548 assert(errors != NULL);
1549
Victor Stinner331a6a52019-05-27 16:39:22 +02001550 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1551 if (_PyStatus_EXCEPTION(status)) {
1552 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001553 }
1554 }
1555
Victor Stinner331a6a52019-05-27 16:39:22 +02001556 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001557}
1558
1559
Victor Stinner331a6a52019-05-27 16:39:22 +02001560static PyStatus
1561config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001562{
Victor Stinner331a6a52019-05-27 16:39:22 +02001563 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001564
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001565 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001566#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001567 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001568#else
Victor Stinnere2510952019-05-02 11:28:57 -04001569
1570#ifdef MS_WINDOWS
1571 if (preconfig->legacy_windows_fs_encoding) {
1572 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001573 status = PyConfig_SetString(config, &config->filesystem_encoding,
1574 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001575 }
1576 else
1577#endif
Victor Stinner20004952019-03-26 02:31:11 +01001578 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001579 status = PyConfig_SetString(config, &config->filesystem_encoding,
1580 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001581 }
Victor Stinnere2510952019-05-02 11:28:57 -04001582#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001583 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001584 status = PyConfig_SetString(config, &config->filesystem_encoding,
1585 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001586 }
Victor Stinnere2510952019-05-02 11:28:57 -04001587#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001588 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001589#ifdef MS_WINDOWS
1590 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001591 status = PyConfig_SetString(config, &config->filesystem_encoding,
1592 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001593#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001594 status = config_get_locale_encoding(config,
1595 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001596#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001597 }
Victor Stinnere2510952019-05-02 11:28:57 -04001598#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001599
Victor Stinner331a6a52019-05-27 16:39:22 +02001600 if (_PyStatus_EXCEPTION(status)) {
1601 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001602 }
1603 }
1604
1605 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001606 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001607#ifdef MS_WINDOWS
1608 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001609 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001610 }
1611 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001612 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001613 }
1614#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001615 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001616#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001617 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1618 if (_PyStatus_EXCEPTION(status)) {
1619 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001620 }
1621 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001622 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001623}
1624
1625
Victor Stinner331a6a52019-05-27 16:39:22 +02001626static PyStatus
1627config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001628{
Victor Stinner331a6a52019-05-27 16:39:22 +02001629 PyStatus status;
1630 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001631
Victor Stinner20004952019-03-26 02:31:11 +01001632 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001633 status = config_read_env_vars(config);
1634 if (_PyStatus_EXCEPTION(status)) {
1635 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001636 }
1637 }
1638
1639 /* -X options */
1640 if (config_get_xoption(config, L"showrefcount")) {
1641 config->show_ref_count = 1;
1642 }
1643 if (config_get_xoption(config, L"showalloccount")) {
1644 config->show_alloc_count = 1;
1645 }
1646
Victor Stinner331a6a52019-05-27 16:39:22 +02001647 status = config_read_complex_options(config);
1648 if (_PyStatus_EXCEPTION(status)) {
1649 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001650 }
1651
Victor Stinner6c785c02018-08-01 17:56:14 +02001652 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001653 status = config_init_home(config);
1654 if (_PyStatus_EXCEPTION(status)) {
1655 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001656 }
1657 }
1658
Steve Dower177a41a2018-11-17 20:41:48 -08001659 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001660 status = config_init_executable(config);
1661 if (_PyStatus_EXCEPTION(status)) {
1662 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001663 }
1664 }
1665
Victor Stinner6c785c02018-08-01 17:56:14 +02001666 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001667 status = _PyConfig_InitPathConfig(config);
1668 if (_PyStatus_EXCEPTION(status)) {
1669 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001670 }
1671 }
1672
1673 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001674 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001675 if (config->faulthandler < 0) {
1676 config->faulthandler = 1;
1677 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001678 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001679 if (config->faulthandler < 0) {
1680 config->faulthandler = 0;
1681 }
1682 if (config->tracemalloc < 0) {
1683 config->tracemalloc = 0;
1684 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001685 if (config->use_hash_seed < 0) {
1686 config->use_hash_seed = 0;
1687 config->hash_seed = 0;
1688 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001689
Victor Stinner70fead22018-08-29 13:45:34 +02001690 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001691 status = config_init_fs_encoding(config, preconfig);
1692 if (_PyStatus_EXCEPTION(status)) {
1693 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001694 }
1695 }
1696
Victor Stinner331a6a52019-05-27 16:39:22 +02001697 status = config_init_stdio_encoding(config, preconfig);
1698 if (_PyStatus_EXCEPTION(status)) {
1699 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001700 }
1701
Victor Stinner62599762019-03-15 16:03:23 +01001702 if (config->argv.length < 1) {
1703 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001704 status = PyWideStringList_Append(&config->argv, L"");
1705 if (_PyStatus_EXCEPTION(status)) {
1706 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001707 }
1708 }
Victor Stinner870b0352019-05-17 03:15:12 +02001709
1710 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001711 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1712 L"default");
1713 if (_PyStatus_EXCEPTION(status)) {
1714 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001715 }
1716 }
1717
1718 if (config->configure_c_stdio < 0) {
1719 config->configure_c_stdio = 1;
1720 }
1721
Victor Stinner331a6a52019-05-27 16:39:22 +02001722 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001723}
Victor Stinner5ed69952018-11-06 15:59:52 +01001724
1725
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001726static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001727config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001728{
1729#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1730 /* don't translate newlines (\r\n <=> \n) */
1731 _setmode(fileno(stdin), O_BINARY);
1732 _setmode(fileno(stdout), O_BINARY);
1733 _setmode(fileno(stderr), O_BINARY);
1734#endif
1735
1736 if (!config->buffered_stdio) {
1737#ifdef HAVE_SETVBUF
1738 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1739 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1740 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1741#else /* !HAVE_SETVBUF */
1742 setbuf(stdin, (char *)NULL);
1743 setbuf(stdout, (char *)NULL);
1744 setbuf(stderr, (char *)NULL);
1745#endif /* !HAVE_SETVBUF */
1746 }
1747 else if (config->interactive) {
1748#ifdef MS_WINDOWS
1749 /* Doesn't have to have line-buffered -- use unbuffered */
1750 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1751 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1752#else /* !MS_WINDOWS */
1753#ifdef HAVE_SETVBUF
1754 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1755 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1756#endif /* HAVE_SETVBUF */
1757#endif /* !MS_WINDOWS */
1758 /* Leave stderr alone - it should be unbuffered anyway. */
1759 }
1760}
1761
1762
1763/* Write the configuration:
1764
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001765 - set Py_xxx global configuration variables
1766 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001767void
Victor Stinner331a6a52019-05-27 16:39:22 +02001768_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001769{
Victor Stinner331a6a52019-05-27 16:39:22 +02001770 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001771
1772 if (config->configure_c_stdio) {
1773 config_init_stdio(config);
1774 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001775
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001776 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001777 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001778 preconfig->isolated = config->isolated;
1779 preconfig->use_environment = config->use_environment;
1780 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001781}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001782
1783
Victor Stinner331a6a52019-05-27 16:39:22 +02001784/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001785
1786static void
Victor Stinner2f549082019-03-29 15:13:46 +01001787config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001788{
Victor Stinner2f549082019-03-29 15:13:46 +01001789 FILE *f = error ? stderr : stdout;
1790
1791 fprintf(f, usage_line, program);
1792 if (error)
1793 fprintf(f, "Try `python -h' for more information.\n");
1794 else {
1795 fputs(usage_1, f);
1796 fputs(usage_2, f);
1797 fputs(usage_3, f);
1798 fprintf(f, usage_4, (wint_t)DELIM);
1799 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1800 fputs(usage_6, f);
1801 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001802}
1803
1804
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001805/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001806static PyStatus
1807config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001808 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001809{
Victor Stinner331a6a52019-05-27 16:39:22 +02001810 PyStatus status;
1811 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001812 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001813 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001814
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001815 _PyOS_ResetGetOpt();
1816 do {
1817 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001818 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001819 if (c == EOF) {
1820 break;
1821 }
1822
1823 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001824 if (config->run_command == NULL) {
1825 /* -c is the last option; following arguments
1826 that look like options are left for the
1827 command to interpret. */
1828 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1829 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1830 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001831 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001832 }
1833 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1834 command[len - 2] = '\n';
1835 command[len - 1] = 0;
1836 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001837 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001838 break;
1839 }
1840
1841 if (c == 'm') {
1842 /* -m is the last option; following arguments
1843 that look like options are left for the
1844 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001845 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001846 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1847 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001848 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001849 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001850 }
1851 break;
1852 }
1853
1854 switch (c) {
1855 case 0:
1856 // Handle long option.
1857 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001858 if (wcscmp(_PyOS_optarg, L"always") == 0
1859 || wcscmp(_PyOS_optarg, L"never") == 0
1860 || wcscmp(_PyOS_optarg, L"default") == 0)
1861 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001862 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1863 _PyOS_optarg);
1864 if (_PyStatus_EXCEPTION(status)) {
1865 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001866 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001867 } else {
1868 fprintf(stderr, "--check-hash-based-pycs must be one of "
1869 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001870 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001871 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001872 }
1873 break;
1874
1875 case 'b':
1876 config->bytes_warning++;
1877 break;
1878
1879 case 'd':
1880 config->parser_debug++;
1881 break;
1882
1883 case 'i':
1884 config->inspect++;
1885 config->interactive++;
1886 break;
1887
Victor Stinner6dcb5422019-03-05 02:44:12 +01001888 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001889 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001890 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001891 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001892 break;
1893
1894 /* case 'J': reserved for Jython */
1895
1896 case 'O':
1897 config->optimization_level++;
1898 break;
1899
1900 case 'B':
1901 config->write_bytecode = 0;
1902 break;
1903
1904 case 's':
1905 config->user_site_directory = 0;
1906 break;
1907
1908 case 'S':
1909 config->site_import = 0;
1910 break;
1911
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001912 case 't':
1913 /* ignored for backwards compatibility */
1914 break;
1915
1916 case 'u':
1917 config->buffered_stdio = 0;
1918 break;
1919
1920 case 'v':
1921 config->verbose++;
1922 break;
1923
1924 case 'x':
1925 config->skip_source_first_line = 1;
1926 break;
1927
1928 case 'h':
1929 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001930 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001931 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001932
1933 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01001934 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001935 break;
1936
1937 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02001938 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
1939 if (_PyStatus_EXCEPTION(status)) {
1940 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001941 }
1942 break;
1943
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001944 case 'q':
1945 config->quiet++;
1946 break;
1947
1948 case 'R':
1949 config->use_hash_seed = 0;
1950 break;
1951
1952 /* This space reserved for other options */
1953
1954 default:
1955 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02001956 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001957 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001958 }
1959 } while (1);
1960
Victor Stinner2f549082019-03-29 15:13:46 +01001961 if (print_version) {
1962 printf("Python %s\n",
1963 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02001964 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01001965 }
1966
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001967 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01001968 && _PyOS_optind < argv->length
1969 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01001970 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001971 {
Victor Stinnerfa153762019-03-20 04:25:38 +01001972 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001973 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001974 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001975 }
1976 }
1977
1978 if (config->run_command != NULL || config->run_module != NULL) {
1979 /* Backup _PyOS_optind */
1980 _PyOS_optind--;
1981 }
1982
Victor Stinnerae239f62019-05-16 17:02:56 +02001983 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001984
Victor Stinner331a6a52019-05-27 16:39:22 +02001985 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001986}
1987
1988
1989#ifdef MS_WINDOWS
1990# define WCSTOK wcstok_s
1991#else
1992# define WCSTOK wcstok
1993#endif
1994
1995/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001996static PyStatus
1997config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001998{
Victor Stinner331a6a52019-05-27 16:39:22 +02001999 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002000 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2001 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002002 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002003 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002004 if (_PyStatus_EXCEPTION(status)) {
2005 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002006 }
2007
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002008 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002009 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002010 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002011 }
2012
2013
2014 wchar_t *warning, *context = NULL;
2015 for (warning = WCSTOK(env, L",", &context);
2016 warning != NULL;
2017 warning = WCSTOK(NULL, L",", &context))
2018 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002019 status = PyWideStringList_Append(warnoptions, warning);
2020 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002021 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002022 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002023 }
2024 }
2025 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002026 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002027}
2028
2029
Victor Stinner331a6a52019-05-27 16:39:22 +02002030static PyStatus
2031config_add_warnoption(PyConfig *config, const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002032{
Victor Stinner331a6a52019-05-27 16:39:22 +02002033 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002034 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002035 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002036 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002037 return PyWideStringList_Append(&config->warnoptions, option);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002038}
2039
2040
Victor Stinner331a6a52019-05-27 16:39:22 +02002041static PyStatus
2042config_init_warnoptions(PyConfig *config,
2043 const PyWideStringList *cmdline_warnoptions,
2044 const PyWideStringList *env_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002045{
Victor Stinner331a6a52019-05-27 16:39:22 +02002046 PyStatus status;
2047
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002048 /* The priority order for warnings configuration is (highest precedence
2049 * first):
2050 *
2051 * - the BytesWarning filter, if needed ('-b', '-bb')
2052 * - any '-W' command line options; then
2053 * - the 'PYTHONWARNINGS' environment variable; then
2054 * - the dev mode filter ('-X dev', 'PYTHONDEVMODE'); then
2055 * - any implicit filters added by _warnings.c/warnings.py
2056 *
2057 * All settings except the last are passed to the warnings module via
2058 * the `sys.warnoptions` list. Since the warnings module works on the basis
2059 * of "the most recently added filter will be checked first", we add
2060 * the lowest precedence entries first so that later entries override them.
2061 */
2062
Victor Stinner20004952019-03-26 02:31:11 +01002063 if (config->dev_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002064 status = config_add_warnoption(config, L"default");
2065 if (_PyStatus_EXCEPTION(status)) {
2066 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002067 }
2068 }
2069
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002070 Py_ssize_t i;
Victor Stinner331a6a52019-05-27 16:39:22 +02002071 const PyWideStringList *options;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002072
Victor Stinner2f549082019-03-29 15:13:46 +01002073 options = env_warnoptions;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002074 for (i = 0; i < options->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002075 status = config_add_warnoption(config, options->items[i]);
2076 if (_PyStatus_EXCEPTION(status)) {
2077 return status;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002078 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002079 }
2080
Victor Stinner2f549082019-03-29 15:13:46 +01002081 options = cmdline_warnoptions;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002082 for (i = 0; i < options->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002083 status = config_add_warnoption(config, options->items[i]);
2084 if (_PyStatus_EXCEPTION(status)) {
2085 return status;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002086 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002087 }
2088
2089 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2090 * don't even try to emit a warning, so we skip setting the filter in that
2091 * case.
2092 */
2093 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002094 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002095 if (config->bytes_warning> 1) {
2096 filter = L"error::BytesWarning";
2097 }
2098 else {
2099 filter = L"default::BytesWarning";
2100 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002101 status = config_add_warnoption(config, filter);
2102 if (_PyStatus_EXCEPTION(status)) {
2103 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002104 }
2105 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002106 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002107}
2108
2109
Victor Stinner331a6a52019-05-27 16:39:22 +02002110static PyStatus
2111config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002112{
Victor Stinner331a6a52019-05-27 16:39:22 +02002113 const PyWideStringList *cmdline_argv = &config->argv;
2114 PyWideStringList config_argv = PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002115
Victor Stinner74f65682019-03-15 15:08:05 +01002116 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002117 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002118 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002119 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2120 if (_PyStatus_EXCEPTION(status)) {
2121 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002122 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002123 }
2124 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002125 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002126 slice.length = cmdline_argv->length - opt_index;
2127 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002128 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2129 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002130 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002131 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002132 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002133
2134 wchar_t *arg0 = NULL;
2135 if (config->run_command != NULL) {
2136 /* Force sys.argv[0] = '-c' */
2137 arg0 = L"-c";
2138 }
2139 else if (config->run_module != NULL) {
2140 /* Force sys.argv[0] = '-m'*/
2141 arg0 = L"-m";
2142 }
Victor Stinner3939c322019-06-25 15:02:43 +02002143 else if (config->run_filename != NULL) {
2144 /* run_filename is converted to an absolute path: update argv */
2145 arg0 = config->run_filename;
2146 }
2147
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002148 if (arg0 != NULL) {
2149 arg0 = _PyMem_RawWcsdup(arg0);
2150 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002151 _PyWideStringList_Clear(&config_argv);
2152 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002153 }
2154
Victor Stinnerfa153762019-03-20 04:25:38 +01002155 PyMem_RawFree(config_argv.items[0]);
2156 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002157 }
2158
Victor Stinner331a6a52019-05-27 16:39:22 +02002159 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002160 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002161 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002162}
2163
2164
Victor Stinner331a6a52019-05-27 16:39:22 +02002165static PyStatus
2166core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002167{
Victor Stinner331a6a52019-05-27 16:39:22 +02002168 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002169
Victor Stinnercab5d072019-05-17 19:01:14 +02002170 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002171 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2172 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002173 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002174 }
2175
Victor Stinner331a6a52019-05-27 16:39:22 +02002176 PyPreConfig preconfig;
Victor Stinner6d1c4672019-05-20 11:02:00 +02002177 _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002178
Victor Stinner331a6a52019-05-27 16:39:22 +02002179 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002180
Victor Stinner331a6a52019-05-27 16:39:22 +02002181 status = _PyPreCmdline_Read(precmdline, &preconfig);
2182 if (_PyStatus_EXCEPTION(status)) {
2183 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002184 }
2185
Victor Stinner331a6a52019-05-27 16:39:22 +02002186 status = _PyPreCmdline_SetConfig(precmdline, config);
2187 if (_PyStatus_EXCEPTION(status)) {
2188 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002189 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002190 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002191}
2192
2193
Victor Stinner3939c322019-06-25 15:02:43 +02002194/* Get run_filename absolute path */
2195static PyStatus
2196config_run_filename_abspath(PyConfig *config)
2197{
2198 if (!config->run_filename) {
2199 return _PyStatus_OK();
2200 }
2201
2202#ifndef MS_WINDOWS
2203 if (_Py_isabs(config->run_filename)) {
2204 /* path is already absolute */
2205 return _PyStatus_OK();
2206 }
2207#endif
2208
2209 wchar_t *abs_filename;
2210 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2211 /* failed to get the absolute path of the command line filename:
2212 ignore the error, keep the relative path */
2213 return _PyStatus_OK();
2214 }
2215 if (abs_filename == NULL) {
2216 return _PyStatus_NO_MEMORY();
2217 }
2218
2219 PyMem_RawFree(config->run_filename);
2220 config->run_filename = abs_filename;
2221 return _PyStatus_OK();
2222}
2223
2224
Victor Stinner331a6a52019-05-27 16:39:22 +02002225static PyStatus
2226config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002227{
Victor Stinner331a6a52019-05-27 16:39:22 +02002228 PyStatus status;
2229 PyWideStringList cmdline_warnoptions = PyWideStringList_INIT;
2230 PyWideStringList env_warnoptions = PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002231
Victor Stinnerae239f62019-05-16 17:02:56 +02002232 if (config->parse_argv < 0) {
2233 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002234 }
Victor Stinner870b0352019-05-17 03:15:12 +02002235
Victor Stinnerfed02e12019-05-17 11:12:09 +02002236 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002237 status = config_init_program_name(config);
2238 if (_PyStatus_EXCEPTION(status)) {
2239 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002240 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002241 }
Victor Stinner2f549082019-03-29 15:13:46 +01002242
Victor Stinnerae239f62019-05-16 17:02:56 +02002243 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002244 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002245 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2246 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002247 goto done;
2248 }
2249
Victor Stinner3939c322019-06-25 15:02:43 +02002250 status = config_run_filename_abspath(config);
2251 if (_PyStatus_EXCEPTION(status)) {
2252 goto done;
2253 }
2254
Victor Stinner331a6a52019-05-27 16:39:22 +02002255 status = config_update_argv(config, opt_index);
2256 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002257 goto done;
2258 }
Victor Stinner2f549082019-03-29 15:13:46 +01002259 }
Victor Stinner3939c322019-06-25 15:02:43 +02002260 else {
2261 status = config_run_filename_abspath(config);
2262 if (_PyStatus_EXCEPTION(status)) {
2263 goto done;
2264 }
2265 }
Victor Stinner2f549082019-03-29 15:13:46 +01002266
Victor Stinner2f549082019-03-29 15:13:46 +01002267 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002268 status = config_init_env_warnoptions(config, &env_warnoptions);
2269 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002270 goto done;
2271 }
2272 }
2273
Victor Stinner331a6a52019-05-27 16:39:22 +02002274 status = config_init_warnoptions(config,
Victor Stinner2f549082019-03-29 15:13:46 +01002275 &cmdline_warnoptions, &env_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002276 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002277 goto done;
2278 }
2279
Victor Stinner331a6a52019-05-27 16:39:22 +02002280 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002281
2282done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002283 _PyWideStringList_Clear(&cmdline_warnoptions);
2284 _PyWideStringList_Clear(&env_warnoptions);
2285 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002286}
2287
2288
Victor Stinner331a6a52019-05-27 16:39:22 +02002289PyStatus
2290_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002291{
Victor Stinner331a6a52019-05-27 16:39:22 +02002292 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2293 if (_PyStatus_EXCEPTION(status)) {
2294 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002295 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002296
Victor Stinner5f38b842019-05-01 02:30:12 +02002297 return _PyArgv_AsWstrList(args, &config->argv);
2298}
2299
2300
Victor Stinner70005ac2019-05-02 15:25:34 -04002301/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2302 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002303PyStatus
2304PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002305{
2306 _PyArgv args = {
2307 .argc = argc,
2308 .use_bytes_argv = 1,
2309 .bytes_argv = argv,
2310 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002311 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002312}
2313
2314
Victor Stinner331a6a52019-05-27 16:39:22 +02002315PyStatus
2316PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002317{
2318 _PyArgv args = {
2319 .argc = argc,
2320 .use_bytes_argv = 0,
2321 .bytes_argv = NULL,
2322 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002323 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002324}
2325
2326
Victor Stinner36242fd2019-07-01 19:13:50 +02002327PyStatus
2328PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2329 Py_ssize_t length, wchar_t **items)
2330{
2331 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2332 if (_PyStatus_EXCEPTION(status)) {
2333 return status;
2334 }
2335
2336 PyWideStringList list2 = {.length = length, .items = items};
2337 if (_PyWideStringList_Copy(list, &list2) < 0) {
2338 return _PyStatus_NO_MEMORY();
2339 }
2340 return _PyStatus_OK();
2341}
2342
2343
Victor Stinner331a6a52019-05-27 16:39:22 +02002344/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002345
2346 * Command line arguments
2347 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002348 * Py_xxx global configuration variables
2349
2350 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002351PyStatus
2352PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002353{
Victor Stinner331a6a52019-05-27 16:39:22 +02002354 PyStatus status;
2355 PyWideStringList orig_argv = PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002356
Victor Stinner331a6a52019-05-27 16:39:22 +02002357 status = _Py_PreInitializeFromConfig(config, NULL);
2358 if (_PyStatus_EXCEPTION(status)) {
2359 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002360 }
2361
Victor Stinner331a6a52019-05-27 16:39:22 +02002362 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002363
Victor Stinner331a6a52019-05-27 16:39:22 +02002364 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2365 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002366 }
2367
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002368 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002369 status = core_read_precmdline(config, &precmdline);
2370 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002371 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002372 }
2373
Victor Stinner870b0352019-05-17 03:15:12 +02002374 assert(config->isolated >= 0);
2375 if (config->isolated) {
2376 config->use_environment = 0;
2377 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002378 }
2379
Victor Stinner331a6a52019-05-27 16:39:22 +02002380 status = config_read_cmdline(config);
2381 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002382 goto done;
2383 }
2384
Victor Stinner331a6a52019-05-27 16:39:22 +02002385 status = config_read(config);
2386 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002387 goto done;
2388 }
2389
Victor Stinnercab5d072019-05-17 19:01:14 +02002390 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002391 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002392 goto done;
2393 }
2394
2395 /* Check config consistency */
2396 assert(config->isolated >= 0);
2397 assert(config->use_environment >= 0);
2398 assert(config->dev_mode >= 0);
2399 assert(config->install_signal_handlers >= 0);
2400 assert(config->use_hash_seed >= 0);
2401 assert(config->faulthandler >= 0);
2402 assert(config->tracemalloc >= 0);
2403 assert(config->site_import >= 0);
2404 assert(config->bytes_warning >= 0);
2405 assert(config->inspect >= 0);
2406 assert(config->interactive >= 0);
2407 assert(config->optimization_level >= 0);
2408 assert(config->parser_debug >= 0);
2409 assert(config->write_bytecode >= 0);
2410 assert(config->verbose >= 0);
2411 assert(config->quiet >= 0);
2412 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002413 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002414 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002415 assert(config->buffered_stdio >= 0);
2416 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002417 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002418 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2419 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002420 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2421 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2422 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002423 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002424 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002425 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002426 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002427 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002428 assert(config->prefix != NULL);
2429 assert(config->base_prefix != NULL);
2430 assert(config->exec_prefix != NULL);
2431 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002432 }
2433 assert(config->filesystem_encoding != NULL);
2434 assert(config->filesystem_errors != NULL);
2435 assert(config->stdio_encoding != NULL);
2436 assert(config->stdio_errors != NULL);
2437#ifdef MS_WINDOWS
2438 assert(config->legacy_windows_stdio >= 0);
2439#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002440 /* -c and -m options are exclusive */
2441 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002442 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002443 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002444 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002445
Victor Stinner331a6a52019-05-27 16:39:22 +02002446 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002447
2448done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002449 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002450 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002451 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002452}
Victor Stinner1075d162019-03-25 23:19:57 +01002453
2454
2455PyObject*
2456_Py_GetConfigsAsDict(void)
2457{
Victor Stinner331a6a52019-05-27 16:39:22 +02002458 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002459 PyObject *dict = NULL;
2460
Victor Stinner331a6a52019-05-27 16:39:22 +02002461 result = PyDict_New();
2462 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002463 goto error;
2464 }
2465
Victor Stinner331a6a52019-05-27 16:39:22 +02002466 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002467 dict = _Py_GetGlobalVariablesAsDict();
2468 if (dict == NULL) {
2469 goto error;
2470 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002471 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002472 goto error;
2473 }
2474 Py_CLEAR(dict);
2475
2476 /* pre config */
2477 PyInterpreterState *interp = _PyInterpreterState_Get();
Victor Stinner331a6a52019-05-27 16:39:22 +02002478 const PyPreConfig *pre_config = &_PyRuntime.preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002479 dict = _PyPreConfig_AsDict(pre_config);
2480 if (dict == NULL) {
2481 goto error;
2482 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002483 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002484 goto error;
2485 }
2486 Py_CLEAR(dict);
2487
2488 /* core config */
Victor Stinner331a6a52019-05-27 16:39:22 +02002489 const PyConfig *config = &interp->config;
2490 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002491 if (dict == NULL) {
2492 goto error;
2493 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002494 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002495 goto error;
2496 }
2497 Py_CLEAR(dict);
2498
Victor Stinner331a6a52019-05-27 16:39:22 +02002499 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002500
2501error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002502 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002503 Py_XDECREF(dict);
2504 return NULL;
2505}