blob: 66b1b305a56033c091424842fe424fa55e482a77 [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);
531 CLEAR(config->prefix);
532 CLEAR(config->base_prefix);
533 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200534 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200535
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200536 CLEAR(config->filesystem_encoding);
537 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200538 CLEAR(config->stdio_encoding);
539 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100540 CLEAR(config->run_command);
541 CLEAR(config->run_module);
542 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400543 CLEAR(config->check_hash_pycs_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200544#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200545}
546
547
Victor Stinnercab5d072019-05-17 19:01:14 +0200548void
Victor Stinner331a6a52019-05-27 16:39:22 +0200549_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200550{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200551 memset(config, 0, sizeof(*config));
552
553 config->_config_version = _Py_CONFIG_VERSION;
Victor Stinner022be022019-05-22 23:58:50 +0200554 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200555 config->isolated = -1;
556 config->use_environment = -1;
557 config->dev_mode = -1;
558 config->install_signal_handlers = 1;
559 config->use_hash_seed = -1;
560 config->faulthandler = -1;
561 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200562 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200563 config->parse_argv = 0;
564 config->site_import = -1;
565 config->bytes_warning = -1;
566 config->inspect = -1;
567 config->interactive = -1;
568 config->optimization_level = -1;
569 config->parser_debug= -1;
570 config->write_bytecode = -1;
571 config->verbose = -1;
572 config->quiet = -1;
573 config->user_site_directory = -1;
574 config->configure_c_stdio = 0;
575 config->buffered_stdio = -1;
576 config->_install_importlib = 1;
577 config->check_hash_pycs_mode = NULL;
578 config->pathconfig_warnings = -1;
579 config->_init_main = 1;
580#ifdef MS_WINDOWS
581 config->legacy_windows_stdio = -1;
582#endif
583}
584
585
586static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200587config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200588{
Victor Stinner331a6a52019-05-27 16:39:22 +0200589 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200590
591 config->isolated = 0;
592 config->use_environment = 1;
593 config->site_import = 1;
594 config->bytes_warning = 0;
595 config->inspect = 0;
596 config->interactive = 0;
597 config->optimization_level = 0;
598 config->parser_debug= 0;
599 config->write_bytecode = 1;
600 config->verbose = 0;
601 config->quiet = 0;
602 config->user_site_directory = 1;
603 config->buffered_stdio = 1;
604 config->pathconfig_warnings = 1;
605#ifdef MS_WINDOWS
606 config->legacy_windows_stdio = 0;
607#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200608}
609
610
Victor Stinner331a6a52019-05-27 16:39:22 +0200611PyStatus
612PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200613{
Victor Stinner331a6a52019-05-27 16:39:22 +0200614 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200615
Victor Stinner022be022019-05-22 23:58:50 +0200616 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200617 config->configure_c_stdio = 1;
618 config->parse_argv = 1;
619
Victor Stinner331a6a52019-05-27 16:39:22 +0200620 return _PyStatus_OK();
Victor Stinnercab5d072019-05-17 19:01:14 +0200621}
622
623
Victor Stinner331a6a52019-05-27 16:39:22 +0200624PyStatus
625PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200626{
Victor Stinner331a6a52019-05-27 16:39:22 +0200627 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200628
Victor Stinner022be022019-05-22 23:58:50 +0200629 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200630 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200631 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200632 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200633 config->dev_mode = 0;
634 config->install_signal_handlers = 0;
635 config->use_hash_seed = 0;
636 config->faulthandler = 0;
637 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200638 config->pathconfig_warnings = 0;
639#ifdef MS_WINDOWS
640 config->legacy_windows_stdio = 0;
641#endif
642
Victor Stinner331a6a52019-05-27 16:39:22 +0200643 return _PyStatus_OK();
Victor Stinnercab5d072019-05-17 19:01:14 +0200644}
645
646
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200647/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200648PyStatus
649PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200650{
Victor Stinner331a6a52019-05-27 16:39:22 +0200651 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
652 if (_PyStatus_EXCEPTION(status)) {
653 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200654 }
655
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200656 wchar_t *str2;
657 if (str != NULL) {
658 str2 = _PyMem_RawWcsdup(str);
659 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200660 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200661 }
662 }
663 else {
664 str2 = NULL;
665 }
666 PyMem_RawFree(*config_str);
667 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200668 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200669}
670
671
Victor Stinner331a6a52019-05-27 16:39:22 +0200672static PyStatus
673config_set_bytes_string(PyConfig *config, wchar_t **config_str,
674 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200675{
Victor Stinner331a6a52019-05-27 16:39:22 +0200676 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
677 if (_PyStatus_EXCEPTION(status)) {
678 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400679 }
680
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200681 wchar_t *str2;
682 if (str != NULL) {
683 size_t len;
684 str2 = Py_DecodeLocale(str, &len);
685 if (str2 == NULL) {
686 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200687 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200688 }
689 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200690 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200691 }
692 }
693 }
694 else {
695 str2 = NULL;
696 }
697 PyMem_RawFree(*config_str);
698 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200699 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200700}
701
702
Victor Stinner331a6a52019-05-27 16:39:22 +0200703#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
704 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400705
706
Victor Stinner70005ac2019-05-02 15:25:34 -0400707/* Decode str using Py_DecodeLocale() and set the result into *config_str.
708 Pre-initialize Python if needed to ensure that encodings are properly
709 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200710PyStatus
711PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200712 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400713{
Victor Stinner331a6a52019-05-27 16:39:22 +0200714 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400715}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200716
717
Victor Stinner331a6a52019-05-27 16:39:22 +0200718PyStatus
719_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200720{
Victor Stinner331a6a52019-05-27 16:39:22 +0200721 PyStatus status;
722 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200723
724#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200725#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200726 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200727 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
728 if (_PyStatus_EXCEPTION(status)) { \
729 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200730 } \
731 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100732#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200733 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200734 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0 ) { \
735 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200736 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200737 } while (0)
738
Victor Stinner6d1c4672019-05-20 11:02:00 +0200739 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100740 COPY_ATTR(isolated);
741 COPY_ATTR(use_environment);
742 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200743 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200744 COPY_ATTR(use_hash_seed);
745 COPY_ATTR(hash_seed);
746 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200747 COPY_ATTR(faulthandler);
748 COPY_ATTR(tracemalloc);
749 COPY_ATTR(import_time);
750 COPY_ATTR(show_ref_count);
751 COPY_ATTR(show_alloc_count);
752 COPY_ATTR(dump_refs);
753 COPY_ATTR(malloc_stats);
754
Victor Stinner124b9eb2018-08-29 01:29:06 +0200755 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200756 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200757 COPY_WSTR_ATTR(home);
758 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200759
Victor Stinnerae239f62019-05-16 17:02:56 +0200760 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100761 COPY_WSTRLIST(argv);
762 COPY_WSTRLIST(warnoptions);
763 COPY_WSTRLIST(xoptions);
764 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200765 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200766
Victor Stinner124b9eb2018-08-29 01:29:06 +0200767 COPY_WSTR_ATTR(executable);
768 COPY_WSTR_ATTR(prefix);
769 COPY_WSTR_ATTR(base_prefix);
770 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200771 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200772
Victor Stinner6c785c02018-08-01 17:56:14 +0200773 COPY_ATTR(site_import);
774 COPY_ATTR(bytes_warning);
775 COPY_ATTR(inspect);
776 COPY_ATTR(interactive);
777 COPY_ATTR(optimization_level);
778 COPY_ATTR(parser_debug);
779 COPY_ATTR(write_bytecode);
780 COPY_ATTR(verbose);
781 COPY_ATTR(quiet);
782 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200783 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200784 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400785 COPY_WSTR_ATTR(filesystem_encoding);
786 COPY_WSTR_ATTR(filesystem_errors);
787 COPY_WSTR_ATTR(stdio_encoding);
788 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200789#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200790 COPY_ATTR(legacy_windows_stdio);
791#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100792 COPY_ATTR(skip_source_first_line);
793 COPY_WSTR_ATTR(run_command);
794 COPY_WSTR_ATTR(run_module);
795 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400796 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200797 COPY_ATTR(pathconfig_warnings);
798 COPY_ATTR(_init_main);
Victor Stinner6c785c02018-08-01 17:56:14 +0200799
800#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200801#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200802#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200803 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200804}
805
806
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100807static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200808config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100809{
810 PyObject *dict;
811
812 dict = PyDict_New();
813 if (dict == NULL) {
814 return NULL;
815 }
816
817#define SET_ITEM(KEY, EXPR) \
818 do { \
819 PyObject *obj = (EXPR); \
820 if (obj == NULL) { \
821 goto fail; \
822 } \
823 int res = PyDict_SetItemString(dict, (KEY), obj); \
824 Py_DECREF(obj); \
825 if (res < 0) { \
826 goto fail; \
827 } \
828 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100829#define SET_ITEM_INT(ATTR) \
830 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
831#define SET_ITEM_UINT(ATTR) \
832 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100833#define FROM_WSTRING(STR) \
834 ((STR != NULL) ? \
835 PyUnicode_FromWideChar(STR, -1) \
836 : (Py_INCREF(Py_None), Py_None))
837#define SET_ITEM_WSTR(ATTR) \
838 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
839#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200840 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100841
Victor Stinner6d1c4672019-05-20 11:02:00 +0200842 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100843 SET_ITEM_INT(isolated);
844 SET_ITEM_INT(use_environment);
845 SET_ITEM_INT(dev_mode);
846 SET_ITEM_INT(install_signal_handlers);
847 SET_ITEM_INT(use_hash_seed);
848 SET_ITEM_UINT(hash_seed);
849 SET_ITEM_INT(faulthandler);
850 SET_ITEM_INT(tracemalloc);
851 SET_ITEM_INT(import_time);
852 SET_ITEM_INT(show_ref_count);
853 SET_ITEM_INT(show_alloc_count);
854 SET_ITEM_INT(dump_refs);
855 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400856 SET_ITEM_WSTR(filesystem_encoding);
857 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100858 SET_ITEM_WSTR(pycache_prefix);
859 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200860 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100861 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100862 SET_ITEM_WSTRLIST(xoptions);
863 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200864 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100865 SET_ITEM_WSTR(home);
866 SET_ITEM_WSTRLIST(module_search_paths);
867 SET_ITEM_WSTR(executable);
868 SET_ITEM_WSTR(prefix);
869 SET_ITEM_WSTR(base_prefix);
870 SET_ITEM_WSTR(exec_prefix);
871 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100872 SET_ITEM_INT(site_import);
873 SET_ITEM_INT(bytes_warning);
874 SET_ITEM_INT(inspect);
875 SET_ITEM_INT(interactive);
876 SET_ITEM_INT(optimization_level);
877 SET_ITEM_INT(parser_debug);
878 SET_ITEM_INT(write_bytecode);
879 SET_ITEM_INT(verbose);
880 SET_ITEM_INT(quiet);
881 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200882 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100883 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400884 SET_ITEM_WSTR(stdio_encoding);
885 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100886#ifdef MS_WINDOWS
887 SET_ITEM_INT(legacy_windows_stdio);
888#endif
889 SET_ITEM_INT(skip_source_first_line);
890 SET_ITEM_WSTR(run_command);
891 SET_ITEM_WSTR(run_module);
892 SET_ITEM_WSTR(run_filename);
893 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400894 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200895 SET_ITEM_INT(pathconfig_warnings);
896 SET_ITEM_INT(_init_main);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100897
898 return dict;
899
900fail:
901 Py_DECREF(dict);
902 return NULL;
903
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100904#undef FROM_WSTRING
905#undef SET_ITEM
906#undef SET_ITEM_INT
907#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100908#undef SET_ITEM_WSTR
909#undef SET_ITEM_WSTRLIST
910}
911
912
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100913static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200914config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200915{
Victor Stinner20004952019-03-26 02:31:11 +0100916 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200917}
918
919
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100920/* Get a copy of the environment variable as wchar_t*.
921 Return 0 on success, but *dest can be NULL.
922 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200923static PyStatus
924config_get_env_dup(PyConfig *config,
925 wchar_t **dest,
926 wchar_t *wname, char *name,
927 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200928{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200929 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100930 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200931
Victor Stinner20004952019-03-26 02:31:11 +0100932 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200933 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200934 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200935 }
936
937#ifdef MS_WINDOWS
938 const wchar_t *var = _wgetenv(wname);
939 if (!var || var[0] == '\0') {
940 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200941 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200942 }
943
Victor Stinner331a6a52019-05-27 16:39:22 +0200944 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +0200945#else
946 const char *var = getenv(name);
947 if (!var || var[0] == '\0') {
948 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200949 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200950 }
951
Victor Stinner331a6a52019-05-27 16:39:22 +0200952 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +0200953#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200954}
955
956
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200957#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200958 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200959
960
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100961static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200962config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200963{
Victor Stinner022be022019-05-22 23:58:50 +0200964 if (config->_config_init != _PyConfig_INIT_COMPAT) {
965 /* Python and Isolated configuration ignore global variables */
966 return;
967 }
968
Victor Stinner6c785c02018-08-01 17:56:14 +0200969#define COPY_FLAG(ATTR, VALUE) \
970 if (config->ATTR == -1) { \
971 config->ATTR = VALUE; \
972 }
973#define COPY_NOT_FLAG(ATTR, VALUE) \
974 if (config->ATTR == -1) { \
975 config->ATTR = !(VALUE); \
976 }
977
Victor Stinner20004952019-03-26 02:31:11 +0100978 COPY_FLAG(isolated, Py_IsolatedFlag);
979 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +0200980 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
981 COPY_FLAG(inspect, Py_InspectFlag);
982 COPY_FLAG(interactive, Py_InteractiveFlag);
983 COPY_FLAG(optimization_level, Py_OptimizeFlag);
984 COPY_FLAG(parser_debug, Py_DebugFlag);
985 COPY_FLAG(verbose, Py_VerboseFlag);
986 COPY_FLAG(quiet, Py_QuietFlag);
987#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200988 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
989#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200990 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +0200991
Victor Stinner6c785c02018-08-01 17:56:14 +0200992 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
993 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
994 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
995 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
996
Victor Stinner6c785c02018-08-01 17:56:14 +0200997#undef COPY_FLAG
998#undef COPY_NOT_FLAG
999}
1000
1001
1002/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001003static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001004config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001005{
1006#define COPY_FLAG(ATTR, VAR) \
1007 if (config->ATTR != -1) { \
1008 VAR = config->ATTR; \
1009 }
1010#define COPY_NOT_FLAG(ATTR, VAR) \
1011 if (config->ATTR != -1) { \
1012 VAR = !config->ATTR; \
1013 }
1014
Victor Stinner20004952019-03-26 02:31:11 +01001015 COPY_FLAG(isolated, Py_IsolatedFlag);
1016 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001017 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1018 COPY_FLAG(inspect, Py_InspectFlag);
1019 COPY_FLAG(interactive, Py_InteractiveFlag);
1020 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1021 COPY_FLAG(parser_debug, Py_DebugFlag);
1022 COPY_FLAG(verbose, Py_VerboseFlag);
1023 COPY_FLAG(quiet, Py_QuietFlag);
1024#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001025 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1026#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001027 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001028
Victor Stinner6c785c02018-08-01 17:56:14 +02001029 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1030 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1031 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1032 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1033
Victor Stinner6c785c02018-08-01 17:56:14 +02001034 /* Random or non-zero hash seed */
1035 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1036 config->hash_seed != 0);
1037
1038#undef COPY_FLAG
1039#undef COPY_NOT_FLAG
1040}
1041
1042
1043/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1044 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001045static PyStatus
1046config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001047{
Victor Stinner331a6a52019-05-27 16:39:22 +02001048 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001049
Victor Stinner6c785c02018-08-01 17:56:14 +02001050 /* If Py_SetProgramName() was called, use its value */
1051 const wchar_t *program_name = _Py_path_config.program_name;
1052 if (program_name != NULL) {
1053 config->program_name = _PyMem_RawWcsdup(program_name);
1054 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001055 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001056 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001057 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001058 }
1059
1060#ifdef __APPLE__
1061 /* On MacOS X, when the Python interpreter is embedded in an
1062 application bundle, it gets executed by a bootstrapping script
1063 that does os.execve() with an argv[0] that's different from the
1064 actual Python executable. This is needed to keep the Finder happy,
1065 or rather, to work around Apple's overly strict requirements of
1066 the process name. However, we still need a usable sys.executable,
1067 so the actual executable path is passed in an environment variable.
1068 See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
1069 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001070 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001071 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001072 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1073 "PYTHONEXECUTABLE environment variable");
1074 if (_PyStatus_EXCEPTION(status)) {
1075 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001076 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001077 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001078 }
1079#ifdef WITH_NEXT_FRAMEWORK
1080 else {
1081 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1082 if (pyvenv_launcher && *pyvenv_launcher) {
1083 /* Used by Mac/Tools/pythonw.c to forward
1084 * the argv0 of the stub executable
1085 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001086 status = CONFIG_SET_BYTES_STR(config,
1087 &config->program_name,
1088 pyvenv_launcher,
1089 "__PYVENV_LAUNCHER__ environment variable");
1090 if (_PyStatus_EXCEPTION(status)) {
1091 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001092 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001093 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001094 }
1095 }
1096#endif /* WITH_NEXT_FRAMEWORK */
1097#endif /* __APPLE__ */
1098
Victor Stinnerfed02e12019-05-17 11:12:09 +02001099 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001100 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001101 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1102 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1103 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001104 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001105 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001106 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001107 }
1108
Victor Stinnerfed02e12019-05-17 11:12:09 +02001109 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001110#ifdef MS_WINDOWS
1111 const wchar_t *default_program_name = L"python";
1112#else
1113 const wchar_t *default_program_name = L"python3";
1114#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001115 status = PyConfig_SetString(config, &config->program_name,
1116 default_program_name);
1117 if (_PyStatus_EXCEPTION(status)) {
1118 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001119 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001120 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001121}
1122
Victor Stinner331a6a52019-05-27 16:39:22 +02001123static PyStatus
1124config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001125{
1126 assert(config->executable == NULL);
1127
1128 /* If Py_SetProgramFullPath() was called, use its value */
1129 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1130 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001131 PyStatus status = PyConfig_SetString(config,
1132 &config->executable,
1133 program_full_path);
1134 if (_PyStatus_EXCEPTION(status)) {
1135 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001136 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001137 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001138 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001139 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001140}
Victor Stinner6c785c02018-08-01 17:56:14 +02001141
Victor Stinner4fffd382019-03-06 01:44:31 +01001142
Victor Stinner6c785c02018-08-01 17:56:14 +02001143static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001144config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001145{
Victor Stinner74f65682019-03-15 15:08:05 +01001146 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001147}
1148
1149
Victor Stinner331a6a52019-05-27 16:39:22 +02001150static PyStatus
1151config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001152{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001153 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001154
1155 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001156 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001157 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001158 PyStatus status = PyConfig_SetString(config, &config->home, home);
1159 if (_PyStatus_EXCEPTION(status)) {
1160 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001161 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001162 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001163 }
1164
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001165 return CONFIG_GET_ENV_DUP(config, &config->home,
1166 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001167}
1168
1169
Victor Stinner331a6a52019-05-27 16:39:22 +02001170static PyStatus
1171config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001172{
Victor Stinner331a6a52019-05-27 16:39:22 +02001173 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001174
1175 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1176 /* Convert a text seed to a numeric one */
1177 if (seed_text && strcmp(seed_text, "random") != 0) {
1178 const char *endptr = seed_text;
1179 unsigned long seed;
1180 errno = 0;
1181 seed = strtoul(seed_text, (char **)&endptr, 10);
1182 if (*endptr != '\0'
1183 || seed > 4294967295UL
1184 || (errno == ERANGE && seed == ULONG_MAX))
1185 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001186 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001187 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001188 }
1189 /* Use a specific hash */
1190 config->use_hash_seed = 1;
1191 config->hash_seed = seed;
1192 }
1193 else {
1194 /* Use a random hash */
1195 config->use_hash_seed = 0;
1196 config->hash_seed = 0;
1197 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001198 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001199}
1200
1201
Victor Stinner6c785c02018-08-01 17:56:14 +02001202static int
1203config_wstr_to_int(const wchar_t *wstr, int *result)
1204{
1205 const wchar_t *endptr = wstr;
1206 errno = 0;
1207 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1208 if (*endptr != '\0' || errno == ERANGE) {
1209 return -1;
1210 }
1211 if (value < INT_MIN || value > INT_MAX) {
1212 return -1;
1213 }
1214
1215 *result = (int)value;
1216 return 0;
1217}
1218
1219
Victor Stinner331a6a52019-05-27 16:39:22 +02001220static PyStatus
1221config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001222{
Victor Stinner331a6a52019-05-27 16:39:22 +02001223 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001224 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001225
Victor Stinner6c785c02018-08-01 17:56:14 +02001226 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001227 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1228 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1229 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1230 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001231
1232 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001233 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001234 if (dont_write_bytecode) {
1235 config->write_bytecode = 0;
1236 }
1237
1238 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001239 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001240 if (no_user_site_directory) {
1241 config->user_site_directory = 0;
1242 }
1243
1244 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001245 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001246 if (unbuffered_stdio) {
1247 config->buffered_stdio = 0;
1248 }
1249
1250#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001251 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001252 "PYTHONLEGACYWINDOWSSTDIO");
1253#endif
1254
Victor Stinner331a6a52019-05-27 16:39:22 +02001255 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001256 config->dump_refs = 1;
1257 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001258 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001259 config->malloc_stats = 1;
1260 }
1261
Victor Stinner331a6a52019-05-27 16:39:22 +02001262 if (config->pythonpath_env == NULL) {
1263 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1264 L"PYTHONPATH", "PYTHONPATH");
1265 if (_PyStatus_EXCEPTION(status)) {
1266 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001267 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001268 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001269
1270 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001271 status = config_init_hash_seed(config);
1272 if (_PyStatus_EXCEPTION(status)) {
1273 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001274 }
1275 }
1276
Victor Stinner331a6a52019-05-27 16:39:22 +02001277 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001278}
1279
1280
Victor Stinner331a6a52019-05-27 16:39:22 +02001281static PyStatus
1282config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001283{
1284 int nframe;
1285 int valid;
1286
Victor Stinner331a6a52019-05-27 16:39:22 +02001287 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001288 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001289 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001290 valid = (nframe >= 0);
1291 }
1292 else {
1293 valid = 0;
1294 }
1295 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001296 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001297 }
1298 config->tracemalloc = nframe;
1299 }
1300
1301 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1302 if (xoption) {
1303 const wchar_t *sep = wcschr(xoption, L'=');
1304 if (sep) {
1305 if (!config_wstr_to_int(sep + 1, &nframe)) {
1306 valid = (nframe >= 0);
1307 }
1308 else {
1309 valid = 0;
1310 }
1311 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001312 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1313 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001314 }
1315 }
1316 else {
1317 /* -X tracemalloc behaves as -X tracemalloc=1 */
1318 nframe = 1;
1319 }
1320 config->tracemalloc = nframe;
1321 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001322 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001323}
1324
1325
Victor Stinner331a6a52019-05-27 16:39:22 +02001326static PyStatus
1327config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001328{
1329 assert(config->pycache_prefix == NULL);
1330
1331 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1332 if (xoption) {
1333 const wchar_t *sep = wcschr(xoption, L'=');
1334 if (sep && wcslen(sep) > 1) {
1335 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1336 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001337 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001338 }
1339 }
1340 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001341 // PYTHONPYCACHEPREFIX env var ignored
1342 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001343 config->pycache_prefix = NULL;
1344 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001345 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001346 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001347
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001348 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1349 L"PYTHONPYCACHEPREFIX",
1350 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001351}
1352
1353
Victor Stinner331a6a52019-05-27 16:39:22 +02001354static PyStatus
1355config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001356{
1357 /* More complex options configured by env var and -X option */
1358 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001359 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001360 || config_get_xoption(config, L"faulthandler")) {
1361 config->faulthandler = 1;
1362 }
1363 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001364 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001365 || config_get_xoption(config, L"importtime")) {
1366 config->import_time = 1;
1367 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001368
Victor Stinner331a6a52019-05-27 16:39:22 +02001369 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001370 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001371 status = config_init_tracemalloc(config);
1372 if (_PyStatus_EXCEPTION(status)) {
1373 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001374 }
1375 }
1376
1377 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001378 status = config_init_pycache_prefix(config);
1379 if (_PyStatus_EXCEPTION(status)) {
1380 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001381 }
1382 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001383 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001384}
1385
1386
Victor Stinner709d23d2019-05-02 14:56:30 -04001387static const wchar_t *
Victor Stinner331a6a52019-05-27 16:39:22 +02001388config_get_stdio_errors(const PyConfig *config)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001389{
1390#ifndef MS_WINDOWS
1391 const char *loc = setlocale(LC_CTYPE, NULL);
1392 if (loc != NULL) {
1393 /* surrogateescape is the default in the legacy C and POSIX locales */
1394 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001395 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001396 }
1397
1398#ifdef PY_COERCE_C_LOCALE
1399 /* surrogateescape is the default in locale coercion target locales */
1400 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001401 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001402 }
1403#endif
1404 }
1405
Victor Stinner709d23d2019-05-02 14:56:30 -04001406 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001407#else
1408 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001409 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001410#endif
1411}
1412
1413
Victor Stinner331a6a52019-05-27 16:39:22 +02001414static PyStatus
1415config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001416{
1417#ifdef MS_WINDOWS
1418 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001419 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001420 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001421#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001422 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001423#else
1424 const char *encoding = nl_langinfo(CODESET);
1425 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001426 return _PyStatus_ERR("failed to get the locale encoding: "
1427 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001428 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001429 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001430 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001431 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001432 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001433#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001434}
1435
1436
Victor Stinner331a6a52019-05-27 16:39:22 +02001437static PyStatus
1438config_init_stdio_encoding(PyConfig *config,
1439 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001440{
Victor Stinner331a6a52019-05-27 16:39:22 +02001441 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001442
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001443 /* If Py_SetStandardStreamEncoding() have been called, use these
1444 parameters. */
1445 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001446 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1447 _Py_StandardStreamEncoding,
1448 "_Py_StandardStreamEncoding");
1449 if (_PyStatus_EXCEPTION(status)) {
1450 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001451 }
1452 }
1453
1454 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001455 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1456 _Py_StandardStreamErrors,
1457 "_Py_StandardStreamErrors");
1458 if (_PyStatus_EXCEPTION(status)) {
1459 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001460 }
1461 }
1462
1463 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001464 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001465 }
1466
1467 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001468 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001469 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001470 char *pythonioencoding = _PyMem_RawStrdup(opt);
1471 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001472 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001473 }
1474
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001475 char *errors = strchr(pythonioencoding, ':');
1476 if (errors) {
1477 *errors = '\0';
1478 errors++;
1479 if (!errors[0]) {
1480 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001481 }
1482 }
1483
1484 /* Does PYTHONIOENCODING contain an encoding? */
1485 if (pythonioencoding[0]) {
1486 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001487 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1488 pythonioencoding,
1489 "PYTHONIOENCODING environment variable");
1490 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001491 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001492 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001493 }
1494 }
1495
1496 /* If the encoding is set but not the error handler,
1497 use "strict" error handler by default.
1498 PYTHONIOENCODING=latin1 behaves as
1499 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001500 if (!errors) {
1501 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001502 }
1503 }
1504
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001505 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001506 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1507 errors,
1508 "PYTHONIOENCODING environment variable");
1509 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001510 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001511 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001512 }
1513 }
1514
1515 PyMem_RawFree(pythonioencoding);
1516 }
1517
1518 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001519 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001520 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001521 status = PyConfig_SetString(config, &config->stdio_encoding,
1522 L"utf-8");
1523 if (_PyStatus_EXCEPTION(status)) {
1524 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001525 }
1526 }
1527 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001528 status = PyConfig_SetString(config, &config->stdio_errors,
1529 L"surrogateescape");
1530 if (_PyStatus_EXCEPTION(status)) {
1531 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001532 }
1533 }
1534 }
1535
1536 /* Choose the default error handler based on the current locale. */
1537 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001538 status = config_get_locale_encoding(config, &config->stdio_encoding);
1539 if (_PyStatus_EXCEPTION(status)) {
1540 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001541 }
1542 }
1543 if (config->stdio_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001544 const wchar_t *errors = config_get_stdio_errors(config);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001545 assert(errors != NULL);
1546
Victor Stinner331a6a52019-05-27 16:39:22 +02001547 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1548 if (_PyStatus_EXCEPTION(status)) {
1549 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001550 }
1551 }
1552
Victor Stinner331a6a52019-05-27 16:39:22 +02001553 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001554}
1555
1556
Victor Stinner331a6a52019-05-27 16:39:22 +02001557static PyStatus
1558config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001559{
Victor Stinner331a6a52019-05-27 16:39:22 +02001560 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001561
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001562 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001563#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001564 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001565#else
Victor Stinnere2510952019-05-02 11:28:57 -04001566
1567#ifdef MS_WINDOWS
1568 if (preconfig->legacy_windows_fs_encoding) {
1569 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001570 status = PyConfig_SetString(config, &config->filesystem_encoding,
1571 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001572 }
1573 else
1574#endif
Victor Stinner20004952019-03-26 02:31:11 +01001575 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001576 status = PyConfig_SetString(config, &config->filesystem_encoding,
1577 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001578 }
Victor Stinnere2510952019-05-02 11:28:57 -04001579#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001580 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001581 status = PyConfig_SetString(config, &config->filesystem_encoding,
1582 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001583 }
Victor Stinnere2510952019-05-02 11:28:57 -04001584#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001585 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001586#ifdef MS_WINDOWS
1587 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001588 status = PyConfig_SetString(config, &config->filesystem_encoding,
1589 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001590#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001591 status = config_get_locale_encoding(config,
1592 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001593#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001594 }
Victor Stinnere2510952019-05-02 11:28:57 -04001595#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001596
Victor Stinner331a6a52019-05-27 16:39:22 +02001597 if (_PyStatus_EXCEPTION(status)) {
1598 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001599 }
1600 }
1601
1602 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001603 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001604#ifdef MS_WINDOWS
1605 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001606 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001607 }
1608 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001609 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001610 }
1611#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001612 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001613#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001614 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1615 if (_PyStatus_EXCEPTION(status)) {
1616 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001617 }
1618 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001619 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001620}
1621
1622
Victor Stinner331a6a52019-05-27 16:39:22 +02001623static PyStatus
1624config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001625{
Victor Stinner331a6a52019-05-27 16:39:22 +02001626 PyStatus status;
1627 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001628
Victor Stinner20004952019-03-26 02:31:11 +01001629 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001630 status = config_read_env_vars(config);
1631 if (_PyStatus_EXCEPTION(status)) {
1632 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001633 }
1634 }
1635
1636 /* -X options */
1637 if (config_get_xoption(config, L"showrefcount")) {
1638 config->show_ref_count = 1;
1639 }
1640 if (config_get_xoption(config, L"showalloccount")) {
1641 config->show_alloc_count = 1;
1642 }
1643
Victor Stinner331a6a52019-05-27 16:39:22 +02001644 status = config_read_complex_options(config);
1645 if (_PyStatus_EXCEPTION(status)) {
1646 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001647 }
1648
Victor Stinner6c785c02018-08-01 17:56:14 +02001649 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001650 status = config_init_home(config);
1651 if (_PyStatus_EXCEPTION(status)) {
1652 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001653 }
1654 }
1655
Steve Dower177a41a2018-11-17 20:41:48 -08001656 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001657 status = config_init_executable(config);
1658 if (_PyStatus_EXCEPTION(status)) {
1659 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001660 }
1661 }
1662
Victor Stinner6c785c02018-08-01 17:56:14 +02001663 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001664 status = _PyConfig_InitPathConfig(config);
1665 if (_PyStatus_EXCEPTION(status)) {
1666 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001667 }
1668 }
1669
1670 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001671 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001672 if (config->faulthandler < 0) {
1673 config->faulthandler = 1;
1674 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001675 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001676 if (config->faulthandler < 0) {
1677 config->faulthandler = 0;
1678 }
1679 if (config->tracemalloc < 0) {
1680 config->tracemalloc = 0;
1681 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001682 if (config->use_hash_seed < 0) {
1683 config->use_hash_seed = 0;
1684 config->hash_seed = 0;
1685 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001686
Victor Stinner70fead22018-08-29 13:45:34 +02001687 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001688 status = config_init_fs_encoding(config, preconfig);
1689 if (_PyStatus_EXCEPTION(status)) {
1690 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001691 }
1692 }
1693
Victor Stinner331a6a52019-05-27 16:39:22 +02001694 status = config_init_stdio_encoding(config, preconfig);
1695 if (_PyStatus_EXCEPTION(status)) {
1696 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001697 }
1698
Victor Stinner62599762019-03-15 16:03:23 +01001699 if (config->argv.length < 1) {
1700 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001701 status = PyWideStringList_Append(&config->argv, L"");
1702 if (_PyStatus_EXCEPTION(status)) {
1703 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001704 }
1705 }
Victor Stinner870b0352019-05-17 03:15:12 +02001706
1707 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001708 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1709 L"default");
1710 if (_PyStatus_EXCEPTION(status)) {
1711 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001712 }
1713 }
1714
1715 if (config->configure_c_stdio < 0) {
1716 config->configure_c_stdio = 1;
1717 }
1718
Victor Stinner331a6a52019-05-27 16:39:22 +02001719 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001720}
Victor Stinner5ed69952018-11-06 15:59:52 +01001721
1722
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001723static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001724config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001725{
1726#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1727 /* don't translate newlines (\r\n <=> \n) */
1728 _setmode(fileno(stdin), O_BINARY);
1729 _setmode(fileno(stdout), O_BINARY);
1730 _setmode(fileno(stderr), O_BINARY);
1731#endif
1732
1733 if (!config->buffered_stdio) {
1734#ifdef HAVE_SETVBUF
1735 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1736 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1737 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1738#else /* !HAVE_SETVBUF */
1739 setbuf(stdin, (char *)NULL);
1740 setbuf(stdout, (char *)NULL);
1741 setbuf(stderr, (char *)NULL);
1742#endif /* !HAVE_SETVBUF */
1743 }
1744 else if (config->interactive) {
1745#ifdef MS_WINDOWS
1746 /* Doesn't have to have line-buffered -- use unbuffered */
1747 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1748 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1749#else /* !MS_WINDOWS */
1750#ifdef HAVE_SETVBUF
1751 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1752 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1753#endif /* HAVE_SETVBUF */
1754#endif /* !MS_WINDOWS */
1755 /* Leave stderr alone - it should be unbuffered anyway. */
1756 }
1757}
1758
1759
1760/* Write the configuration:
1761
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001762 - set Py_xxx global configuration variables
1763 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001764void
Victor Stinner331a6a52019-05-27 16:39:22 +02001765_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001766{
Victor Stinner331a6a52019-05-27 16:39:22 +02001767 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001768
1769 if (config->configure_c_stdio) {
1770 config_init_stdio(config);
1771 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001772
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001773 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001774 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001775 preconfig->isolated = config->isolated;
1776 preconfig->use_environment = config->use_environment;
1777 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001778}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001779
1780
Victor Stinner331a6a52019-05-27 16:39:22 +02001781/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001782
1783static void
Victor Stinner2f549082019-03-29 15:13:46 +01001784config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001785{
Victor Stinner2f549082019-03-29 15:13:46 +01001786 FILE *f = error ? stderr : stdout;
1787
1788 fprintf(f, usage_line, program);
1789 if (error)
1790 fprintf(f, "Try `python -h' for more information.\n");
1791 else {
1792 fputs(usage_1, f);
1793 fputs(usage_2, f);
1794 fputs(usage_3, f);
1795 fprintf(f, usage_4, (wint_t)DELIM);
1796 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1797 fputs(usage_6, f);
1798 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001799}
1800
1801
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001802/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001803static PyStatus
1804config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001805 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001806{
Victor Stinner331a6a52019-05-27 16:39:22 +02001807 PyStatus status;
1808 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001809 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001810 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001811
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001812 _PyOS_ResetGetOpt();
1813 do {
1814 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001815 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001816 if (c == EOF) {
1817 break;
1818 }
1819
1820 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001821 if (config->run_command == NULL) {
1822 /* -c is the last option; following arguments
1823 that look like options are left for the
1824 command to interpret. */
1825 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1826 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1827 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001828 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001829 }
1830 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1831 command[len - 2] = '\n';
1832 command[len - 1] = 0;
1833 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001834 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001835 break;
1836 }
1837
1838 if (c == 'm') {
1839 /* -m is the last option; following arguments
1840 that look like options are left for the
1841 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001842 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001843 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1844 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001845 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001846 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001847 }
1848 break;
1849 }
1850
1851 switch (c) {
1852 case 0:
1853 // Handle long option.
1854 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001855 if (wcscmp(_PyOS_optarg, L"always") == 0
1856 || wcscmp(_PyOS_optarg, L"never") == 0
1857 || wcscmp(_PyOS_optarg, L"default") == 0)
1858 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001859 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1860 _PyOS_optarg);
1861 if (_PyStatus_EXCEPTION(status)) {
1862 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001863 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001864 } else {
1865 fprintf(stderr, "--check-hash-based-pycs must be one of "
1866 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001867 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001868 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001869 }
1870 break;
1871
1872 case 'b':
1873 config->bytes_warning++;
1874 break;
1875
1876 case 'd':
1877 config->parser_debug++;
1878 break;
1879
1880 case 'i':
1881 config->inspect++;
1882 config->interactive++;
1883 break;
1884
Victor Stinner6dcb5422019-03-05 02:44:12 +01001885 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001886 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001887 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001888 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001889 break;
1890
1891 /* case 'J': reserved for Jython */
1892
1893 case 'O':
1894 config->optimization_level++;
1895 break;
1896
1897 case 'B':
1898 config->write_bytecode = 0;
1899 break;
1900
1901 case 's':
1902 config->user_site_directory = 0;
1903 break;
1904
1905 case 'S':
1906 config->site_import = 0;
1907 break;
1908
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001909 case 't':
1910 /* ignored for backwards compatibility */
1911 break;
1912
1913 case 'u':
1914 config->buffered_stdio = 0;
1915 break;
1916
1917 case 'v':
1918 config->verbose++;
1919 break;
1920
1921 case 'x':
1922 config->skip_source_first_line = 1;
1923 break;
1924
1925 case 'h':
1926 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001927 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001928 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001929
1930 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01001931 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001932 break;
1933
1934 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02001935 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
1936 if (_PyStatus_EXCEPTION(status)) {
1937 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001938 }
1939 break;
1940
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001941 case 'q':
1942 config->quiet++;
1943 break;
1944
1945 case 'R':
1946 config->use_hash_seed = 0;
1947 break;
1948
1949 /* This space reserved for other options */
1950
1951 default:
1952 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02001953 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001954 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001955 }
1956 } while (1);
1957
Victor Stinner2f549082019-03-29 15:13:46 +01001958 if (print_version) {
1959 printf("Python %s\n",
1960 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02001961 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01001962 }
1963
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001964 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01001965 && _PyOS_optind < argv->length
1966 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01001967 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001968 {
Victor Stinnerfa153762019-03-20 04:25:38 +01001969 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001970 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001971 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001972 }
1973 }
1974
1975 if (config->run_command != NULL || config->run_module != NULL) {
1976 /* Backup _PyOS_optind */
1977 _PyOS_optind--;
1978 }
1979
Victor Stinnerae239f62019-05-16 17:02:56 +02001980 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001981
Victor Stinner331a6a52019-05-27 16:39:22 +02001982 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001983}
1984
1985
1986#ifdef MS_WINDOWS
1987# define WCSTOK wcstok_s
1988#else
1989# define WCSTOK wcstok
1990#endif
1991
1992/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001993static PyStatus
1994config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001995{
Victor Stinner331a6a52019-05-27 16:39:22 +02001996 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001997 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
1998 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001999 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002000 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002001 if (_PyStatus_EXCEPTION(status)) {
2002 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002003 }
2004
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002005 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002006 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002007 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002008 }
2009
2010
2011 wchar_t *warning, *context = NULL;
2012 for (warning = WCSTOK(env, L",", &context);
2013 warning != NULL;
2014 warning = WCSTOK(NULL, L",", &context))
2015 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002016 status = PyWideStringList_Append(warnoptions, warning);
2017 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002018 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002019 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002020 }
2021 }
2022 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002023 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002024}
2025
2026
Victor Stinner331a6a52019-05-27 16:39:22 +02002027static PyStatus
2028config_add_warnoption(PyConfig *config, const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002029{
Victor Stinner331a6a52019-05-27 16:39:22 +02002030 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002031 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002032 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002033 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002034 return PyWideStringList_Append(&config->warnoptions, option);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002035}
2036
2037
Victor Stinner331a6a52019-05-27 16:39:22 +02002038static PyStatus
2039config_init_warnoptions(PyConfig *config,
2040 const PyWideStringList *cmdline_warnoptions,
2041 const PyWideStringList *env_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002042{
Victor Stinner331a6a52019-05-27 16:39:22 +02002043 PyStatus status;
2044
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002045 /* The priority order for warnings configuration is (highest precedence
2046 * first):
2047 *
2048 * - the BytesWarning filter, if needed ('-b', '-bb')
2049 * - any '-W' command line options; then
2050 * - the 'PYTHONWARNINGS' environment variable; then
2051 * - the dev mode filter ('-X dev', 'PYTHONDEVMODE'); then
2052 * - any implicit filters added by _warnings.c/warnings.py
2053 *
2054 * All settings except the last are passed to the warnings module via
2055 * the `sys.warnoptions` list. Since the warnings module works on the basis
2056 * of "the most recently added filter will be checked first", we add
2057 * the lowest precedence entries first so that later entries override them.
2058 */
2059
Victor Stinner20004952019-03-26 02:31:11 +01002060 if (config->dev_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002061 status = config_add_warnoption(config, L"default");
2062 if (_PyStatus_EXCEPTION(status)) {
2063 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002064 }
2065 }
2066
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002067 Py_ssize_t i;
Victor Stinner331a6a52019-05-27 16:39:22 +02002068 const PyWideStringList *options;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002069
Victor Stinner2f549082019-03-29 15:13:46 +01002070 options = env_warnoptions;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002071 for (i = 0; i < options->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002072 status = config_add_warnoption(config, options->items[i]);
2073 if (_PyStatus_EXCEPTION(status)) {
2074 return status;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002075 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002076 }
2077
Victor Stinner2f549082019-03-29 15:13:46 +01002078 options = cmdline_warnoptions;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002079 for (i = 0; i < options->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002080 status = config_add_warnoption(config, options->items[i]);
2081 if (_PyStatus_EXCEPTION(status)) {
2082 return status;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002083 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002084 }
2085
2086 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2087 * don't even try to emit a warning, so we skip setting the filter in that
2088 * case.
2089 */
2090 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002091 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002092 if (config->bytes_warning> 1) {
2093 filter = L"error::BytesWarning";
2094 }
2095 else {
2096 filter = L"default::BytesWarning";
2097 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002098 status = config_add_warnoption(config, filter);
2099 if (_PyStatus_EXCEPTION(status)) {
2100 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002101 }
2102 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002103 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002104}
2105
2106
Victor Stinner331a6a52019-05-27 16:39:22 +02002107static PyStatus
2108config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002109{
Victor Stinner331a6a52019-05-27 16:39:22 +02002110 const PyWideStringList *cmdline_argv = &config->argv;
2111 PyWideStringList config_argv = PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002112
Victor Stinner74f65682019-03-15 15:08:05 +01002113 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002114 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002115 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002116 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2117 if (_PyStatus_EXCEPTION(status)) {
2118 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002119 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002120 }
2121 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002122 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002123 slice.length = cmdline_argv->length - opt_index;
2124 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002125 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2126 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002127 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002128 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002129 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002130
2131 wchar_t *arg0 = NULL;
2132 if (config->run_command != NULL) {
2133 /* Force sys.argv[0] = '-c' */
2134 arg0 = L"-c";
2135 }
2136 else if (config->run_module != NULL) {
2137 /* Force sys.argv[0] = '-m'*/
2138 arg0 = L"-m";
2139 }
2140 if (arg0 != NULL) {
2141 arg0 = _PyMem_RawWcsdup(arg0);
2142 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002143 _PyWideStringList_Clear(&config_argv);
2144 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002145 }
2146
Victor Stinnerfa153762019-03-20 04:25:38 +01002147 PyMem_RawFree(config_argv.items[0]);
2148 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002149 }
2150
Victor Stinner331a6a52019-05-27 16:39:22 +02002151 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002152 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002153 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002154}
2155
2156
Victor Stinner331a6a52019-05-27 16:39:22 +02002157static PyStatus
2158core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002159{
Victor Stinner331a6a52019-05-27 16:39:22 +02002160 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002161
Victor Stinnercab5d072019-05-17 19:01:14 +02002162 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002163 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2164 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002165 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002166 }
2167
Victor Stinner331a6a52019-05-27 16:39:22 +02002168 PyPreConfig preconfig;
Victor Stinner6d1c4672019-05-20 11:02:00 +02002169 _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002170
Victor Stinner331a6a52019-05-27 16:39:22 +02002171 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002172
Victor Stinner331a6a52019-05-27 16:39:22 +02002173 status = _PyPreCmdline_Read(precmdline, &preconfig);
2174 if (_PyStatus_EXCEPTION(status)) {
2175 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002176 }
2177
Victor Stinner331a6a52019-05-27 16:39:22 +02002178 status = _PyPreCmdline_SetConfig(precmdline, config);
2179 if (_PyStatus_EXCEPTION(status)) {
2180 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002181 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002182 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002183}
2184
2185
Victor Stinner331a6a52019-05-27 16:39:22 +02002186static PyStatus
2187config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002188{
Victor Stinner331a6a52019-05-27 16:39:22 +02002189 PyStatus status;
2190 PyWideStringList cmdline_warnoptions = PyWideStringList_INIT;
2191 PyWideStringList env_warnoptions = PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002192
Victor Stinnerae239f62019-05-16 17:02:56 +02002193 if (config->parse_argv < 0) {
2194 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002195 }
Victor Stinner870b0352019-05-17 03:15:12 +02002196
Victor Stinnerfed02e12019-05-17 11:12:09 +02002197 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002198 status = config_init_program_name(config);
2199 if (_PyStatus_EXCEPTION(status)) {
2200 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002201 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002202 }
Victor Stinner2f549082019-03-29 15:13:46 +01002203
Victor Stinnerae239f62019-05-16 17:02:56 +02002204 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002205 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002206 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2207 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002208 goto done;
2209 }
2210
Victor Stinner331a6a52019-05-27 16:39:22 +02002211 status = config_update_argv(config, opt_index);
2212 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002213 goto done;
2214 }
Victor Stinner2f549082019-03-29 15:13:46 +01002215 }
2216
Victor Stinner2f549082019-03-29 15:13:46 +01002217 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002218 status = config_init_env_warnoptions(config, &env_warnoptions);
2219 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002220 goto done;
2221 }
2222 }
2223
Victor Stinner331a6a52019-05-27 16:39:22 +02002224 status = config_init_warnoptions(config,
Victor Stinner2f549082019-03-29 15:13:46 +01002225 &cmdline_warnoptions, &env_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002226 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002227 goto done;
2228 }
2229
Victor Stinner331a6a52019-05-27 16:39:22 +02002230 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002231
2232done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002233 _PyWideStringList_Clear(&cmdline_warnoptions);
2234 _PyWideStringList_Clear(&env_warnoptions);
2235 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002236}
2237
2238
Victor Stinner331a6a52019-05-27 16:39:22 +02002239PyStatus
2240_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002241{
Victor Stinner331a6a52019-05-27 16:39:22 +02002242 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2243 if (_PyStatus_EXCEPTION(status)) {
2244 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002245 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002246
Victor Stinner5f38b842019-05-01 02:30:12 +02002247 return _PyArgv_AsWstrList(args, &config->argv);
2248}
2249
2250
Victor Stinner70005ac2019-05-02 15:25:34 -04002251/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2252 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002253PyStatus
2254PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002255{
2256 _PyArgv args = {
2257 .argc = argc,
2258 .use_bytes_argv = 1,
2259 .bytes_argv = argv,
2260 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002261 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002262}
2263
2264
Victor Stinner331a6a52019-05-27 16:39:22 +02002265PyStatus
2266PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002267{
2268 _PyArgv args = {
2269 .argc = argc,
2270 .use_bytes_argv = 0,
2271 .bytes_argv = NULL,
2272 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002273 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002274}
2275
2276
Victor Stinner331a6a52019-05-27 16:39:22 +02002277/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002278
2279 * Command line arguments
2280 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002281 * Py_xxx global configuration variables
2282
2283 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002284PyStatus
2285PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002286{
Victor Stinner331a6a52019-05-27 16:39:22 +02002287 PyStatus status;
2288 PyWideStringList orig_argv = PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002289
Victor Stinner331a6a52019-05-27 16:39:22 +02002290 status = _Py_PreInitializeFromConfig(config, NULL);
2291 if (_PyStatus_EXCEPTION(status)) {
2292 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002293 }
2294
Victor Stinner331a6a52019-05-27 16:39:22 +02002295 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002296
Victor Stinner331a6a52019-05-27 16:39:22 +02002297 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2298 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002299 }
2300
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002301 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002302 status = core_read_precmdline(config, &precmdline);
2303 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002304 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002305 }
2306
Victor Stinner870b0352019-05-17 03:15:12 +02002307 assert(config->isolated >= 0);
2308 if (config->isolated) {
2309 config->use_environment = 0;
2310 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002311 }
2312
Victor Stinner331a6a52019-05-27 16:39:22 +02002313 status = config_read_cmdline(config);
2314 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002315 goto done;
2316 }
2317
Victor Stinner331a6a52019-05-27 16:39:22 +02002318 status = config_read(config);
2319 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002320 goto done;
2321 }
2322
Victor Stinnercab5d072019-05-17 19:01:14 +02002323 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002324 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002325 goto done;
2326 }
2327
2328 /* Check config consistency */
2329 assert(config->isolated >= 0);
2330 assert(config->use_environment >= 0);
2331 assert(config->dev_mode >= 0);
2332 assert(config->install_signal_handlers >= 0);
2333 assert(config->use_hash_seed >= 0);
2334 assert(config->faulthandler >= 0);
2335 assert(config->tracemalloc >= 0);
2336 assert(config->site_import >= 0);
2337 assert(config->bytes_warning >= 0);
2338 assert(config->inspect >= 0);
2339 assert(config->interactive >= 0);
2340 assert(config->optimization_level >= 0);
2341 assert(config->parser_debug >= 0);
2342 assert(config->write_bytecode >= 0);
2343 assert(config->verbose >= 0);
2344 assert(config->quiet >= 0);
2345 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002346 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002347 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002348 assert(config->buffered_stdio >= 0);
2349 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002350 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002351 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2352 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002353 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2354 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2355 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002356 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002357 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002358 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002359 assert(config->executable != NULL);
2360 assert(config->prefix != NULL);
2361 assert(config->base_prefix != NULL);
2362 assert(config->exec_prefix != NULL);
2363 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002364 }
2365 assert(config->filesystem_encoding != NULL);
2366 assert(config->filesystem_errors != NULL);
2367 assert(config->stdio_encoding != NULL);
2368 assert(config->stdio_errors != NULL);
2369#ifdef MS_WINDOWS
2370 assert(config->legacy_windows_stdio >= 0);
2371#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002372 /* -c and -m options are exclusive */
2373 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002374 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002375 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002376 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002377
Victor Stinner331a6a52019-05-27 16:39:22 +02002378 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002379
2380done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002381 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002382 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002383 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002384}
Victor Stinner1075d162019-03-25 23:19:57 +01002385
2386
2387PyObject*
2388_Py_GetConfigsAsDict(void)
2389{
Victor Stinner331a6a52019-05-27 16:39:22 +02002390 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002391 PyObject *dict = NULL;
2392
Victor Stinner331a6a52019-05-27 16:39:22 +02002393 result = PyDict_New();
2394 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002395 goto error;
2396 }
2397
Victor Stinner331a6a52019-05-27 16:39:22 +02002398 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002399 dict = _Py_GetGlobalVariablesAsDict();
2400 if (dict == NULL) {
2401 goto error;
2402 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002403 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002404 goto error;
2405 }
2406 Py_CLEAR(dict);
2407
2408 /* pre config */
2409 PyInterpreterState *interp = _PyInterpreterState_Get();
Victor Stinner331a6a52019-05-27 16:39:22 +02002410 const PyPreConfig *pre_config = &_PyRuntime.preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002411 dict = _PyPreConfig_AsDict(pre_config);
2412 if (dict == NULL) {
2413 goto error;
2414 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002415 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002416 goto error;
2417 }
2418 Py_CLEAR(dict);
2419
2420 /* core config */
Victor Stinner331a6a52019-05-27 16:39:22 +02002421 const PyConfig *config = &interp->config;
2422 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002423 if (dict == NULL) {
2424 goto error;
2425 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002426 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002427 goto error;
2428 }
2429 Py_CLEAR(dict);
2430
Victor Stinner331a6a52019-05-27 16:39:22 +02002431 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002432
2433error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002434 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002435 Py_XDECREF(dict);
2436 return NULL;
2437}