blob: caa9bf5f5689e49a7824fbb12e5d31ec0a530e80 [file] [log] [blame]
Victor Stinner6c785c02018-08-01 17:56:14 +02001#include "Python.h"
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002#include "osdefs.h" /* DELIM */
Victor Stinner9fc57a32018-11-07 00:44:03 +01003#include "pycore_fileutils.h"
Victor Stinner95e2cbf2019-03-01 16:25:19 +01004#include "pycore_getopt.h"
Victor Stinnerfcdb0272019-09-23 14:45:47 +02005#include "pycore_initconfig.h"
6#include "pycore_pathconfig.h"
7#include "pycore_pyerrors.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01008#include "pycore_pylifecycle.h"
9#include "pycore_pymem.h"
Victor Stinner6d5ee972019-03-23 12:05:43 +010010#include "pycore_pystate.h" /* _PyRuntime */
Victor Stinner95e2cbf2019-03-01 16:25:19 +010011#include <locale.h> /* setlocale() */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020012#ifdef HAVE_LANGINFO_H
Victor Stinner95e2cbf2019-03-01 16:25:19 +010013# include <langinfo.h> /* nl_langinfo(CODESET) */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020014#endif
Victor Stinner95e2cbf2019-03-01 16:25:19 +010015#if defined(MS_WINDOWS) || defined(__CYGWIN__)
16# include <windows.h> /* GetACP() */
17# ifdef HAVE_IO_H
18# include <io.h>
19# endif
20# ifdef HAVE_FCNTL_H
21# include <fcntl.h> /* O_BINARY */
22# endif
Victor Stinnerb2457ef2018-08-29 13:25:36 +020023#endif
24
Victor Stinner6c785c02018-08-01 17:56:14 +020025
Victor Stinner95e2cbf2019-03-01 16:25:19 +010026/* --- Command line options --------------------------------------- */
27
Victor Stinner95e2cbf2019-03-01 16:25:19 +010028/* Short usage message (with %s for argv0) */
29static const char usage_line[] =
30"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
31
32/* Long usage message, split into parts < 512 bytes */
33static const char usage_1[] = "\
34Options and arguments (and corresponding environment variables):\n\
35-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
36 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
37-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
38-c cmd : program passed in as string (terminates option list)\n\
39-d : debug output from parser; also PYTHONDEBUG=x\n\
40-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
41-h : print this help message and exit (also --help)\n\
42";
43static const char usage_2[] = "\
44-i : inspect interactively after running script; forces a prompt even\n\
45 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
46-I : isolate Python from the user's environment (implies -E and -s)\n\
47-m mod : run library module as a script (terminates option list)\n\
48-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
49 .pyc extension; also PYTHONOPTIMIZE=x\n\
50-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
51 .pyc extension\n\
52-q : don't print version and copyright messages on interactive startup\n\
53-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
54-S : don't imply 'import site' on initialization\n\
55";
56static const char usage_3[] = "\
57-u : force the stdout and stderr streams to be unbuffered;\n\
58 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
59-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
60 can be supplied multiple times to increase verbosity\n\
61-V : print the Python version number and exit (also --version)\n\
62 when given twice, print more information about the build\n\
63-W arg : warning control; arg is action:message:category:module:lineno\n\
64 also PYTHONWARNINGS=arg\n\
65-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
66-X opt : set implementation-specific option\n\
67--check-hash-based-pycs always|default|never:\n\
68 control how Python invalidates hash-based .pyc files\n\
69";
70static const char usage_4[] = "\
71file : program read from script file\n\
72- : program read from stdin (default; interactive mode if a tty)\n\
73arg ...: arguments passed to program in sys.argv[1:]\n\n\
74Other environment variables:\n\
75PYTHONSTARTUP: file executed on interactive startup (no default)\n\
76PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
77 default module search path. The result is sys.path.\n\
78";
79static const char usage_5[] =
80"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
81" The default module search path uses %s.\n"
82"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
83"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
84"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
85static const char usage_6[] =
86"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Serhiy Storchakae9c90aa2019-08-24 12:49:27 +030087" to seed the hashes of str and bytes objects. It can also be set to an\n"
88" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +010089" predictable seed.\n"
90"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
91" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
92" hooks.\n"
93"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
94" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
95" locale coercion and locale compatibility warnings on stderr.\n"
96"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
97" debugger. It can be set to the callable of your debugger of choice.\n"
98"PYTHONDEVMODE: enable the development mode.\n"
99"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
100
101#if defined(MS_WINDOWS)
102# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
103#else
104# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
105#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200106
107
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100108/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200109
Victor Stinner6c785c02018-08-01 17:56:14 +0200110/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200111 stdin and stdout error handler to "surrogateescape". */
112int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200113int Py_DebugFlag = 0; /* Needed by parser.c */
114int Py_VerboseFlag = 0; /* Needed by import.c */
115int Py_QuietFlag = 0; /* Needed by sysmodule.c */
116int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
117int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
118int Py_OptimizeFlag = 0; /* Needed by compile.c */
119int Py_NoSiteFlag = 0; /* Suppress 'import site' */
120int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
121int Py_FrozenFlag = 0; /* Needed by getpath.c */
122int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
123int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
124int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
125int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
126int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
127int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
128#ifdef MS_WINDOWS
129int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
130int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
131#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200132
133
Victor Stinner1075d162019-03-25 23:19:57 +0100134static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100135_Py_GetGlobalVariablesAsDict(void)
136{
137 PyObject *dict, *obj;
138
139 dict = PyDict_New();
140 if (dict == NULL) {
141 return NULL;
142 }
143
144#define SET_ITEM(KEY, EXPR) \
145 do { \
146 obj = (EXPR); \
147 if (obj == NULL) { \
148 return NULL; \
149 } \
150 int res = PyDict_SetItemString(dict, (KEY), obj); \
151 Py_DECREF(obj); \
152 if (res < 0) { \
153 goto fail; \
154 } \
155 } while (0)
156#define SET_ITEM_INT(VAR) \
157 SET_ITEM(#VAR, PyLong_FromLong(VAR))
158#define FROM_STRING(STR) \
159 ((STR != NULL) ? \
160 PyUnicode_FromString(STR) \
161 : (Py_INCREF(Py_None), Py_None))
162#define SET_ITEM_STR(VAR) \
163 SET_ITEM(#VAR, FROM_STRING(VAR))
164
165 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
166 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
167 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
168 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
169
170 SET_ITEM_INT(Py_UTF8Mode);
171 SET_ITEM_INT(Py_DebugFlag);
172 SET_ITEM_INT(Py_VerboseFlag);
173 SET_ITEM_INT(Py_QuietFlag);
174 SET_ITEM_INT(Py_InteractiveFlag);
175 SET_ITEM_INT(Py_InspectFlag);
176
177 SET_ITEM_INT(Py_OptimizeFlag);
178 SET_ITEM_INT(Py_NoSiteFlag);
179 SET_ITEM_INT(Py_BytesWarningFlag);
180 SET_ITEM_INT(Py_FrozenFlag);
181 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
182 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
183 SET_ITEM_INT(Py_NoUserSiteDirectory);
184 SET_ITEM_INT(Py_UnbufferedStdioFlag);
185 SET_ITEM_INT(Py_HashRandomizationFlag);
186 SET_ITEM_INT(Py_IsolatedFlag);
187
188#ifdef MS_WINDOWS
189 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
190 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
191#endif
192
193 return dict;
194
195fail:
196 Py_DECREF(dict);
197 return NULL;
198
199#undef FROM_STRING
200#undef SET_ITEM
201#undef SET_ITEM_INT
202#undef SET_ITEM_STR
203}
204
205
Victor Stinner331a6a52019-05-27 16:39:22 +0200206/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200207
Victor Stinner331a6a52019-05-27 16:39:22 +0200208PyStatus PyStatus_Ok(void)
209{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200210
Victor Stinner331a6a52019-05-27 16:39:22 +0200211PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200212{
Victor Stinner331a6a52019-05-27 16:39:22 +0200213 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner871ff772019-05-17 23:54:00 +0200214 .err_msg = err_msg};
215}
216
Victor Stinner331a6a52019-05-27 16:39:22 +0200217PyStatus PyStatus_NoMemory(void)
218{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200219
Victor Stinner331a6a52019-05-27 16:39:22 +0200220PyStatus PyStatus_Exit(int exitcode)
221{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200222
223
Victor Stinner331a6a52019-05-27 16:39:22 +0200224int PyStatus_IsError(PyStatus status)
225{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200226
Victor Stinner331a6a52019-05-27 16:39:22 +0200227int PyStatus_IsExit(PyStatus status)
228{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200229
Victor Stinner331a6a52019-05-27 16:39:22 +0200230int PyStatus_Exception(PyStatus status)
231{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200232
233
Victor Stinner331a6a52019-05-27 16:39:22 +0200234/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100235
236#ifndef NDEBUG
237int
Victor Stinner331a6a52019-05-27 16:39:22 +0200238_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100239{
240 assert(list->length >= 0);
241 if (list->length != 0) {
242 assert(list->items != NULL);
243 }
244 for (Py_ssize_t i = 0; i < list->length; i++) {
245 assert(list->items[i] != NULL);
246 }
247 return 1;
248}
249#endif /* Py_DEBUG */
250
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100251
Victor Stinner6c785c02018-08-01 17:56:14 +0200252void
Victor Stinner331a6a52019-05-27 16:39:22 +0200253_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200254{
Victor Stinner331a6a52019-05-27 16:39:22 +0200255 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100256 for (Py_ssize_t i=0; i < list->length; i++) {
257 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200258 }
Victor Stinner74f65682019-03-15 15:08:05 +0100259 PyMem_RawFree(list->items);
260 list->length = 0;
261 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200262}
263
264
Victor Stinner74f65682019-03-15 15:08:05 +0100265int
Victor Stinner331a6a52019-05-27 16:39:22 +0200266_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200267{
Victor Stinner331a6a52019-05-27 16:39:22 +0200268 assert(_PyWideStringList_CheckConsistency(list));
269 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100270
271 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200272 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100273 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300274 }
Victor Stinner74f65682019-03-15 15:08:05 +0100275
Victor Stinnerfb4ae152019-09-30 01:40:17 +0200276 PyWideStringList copy = _PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100277
278 size_t size = list2->length * sizeof(list2->items[0]);
279 copy.items = PyMem_RawMalloc(size);
280 if (copy.items == NULL) {
281 return -1;
282 }
283
284 for (Py_ssize_t i=0; i < list2->length; i++) {
285 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
286 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200287 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100288 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200289 }
Victor Stinner74f65682019-03-15 15:08:05 +0100290 copy.items[i] = item;
291 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200292 }
Victor Stinner74f65682019-03-15 15:08:05 +0100293
Victor Stinner331a6a52019-05-27 16:39:22 +0200294 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100295 *list = copy;
296 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200297}
298
299
Victor Stinner331a6a52019-05-27 16:39:22 +0200300PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100301PyWideStringList_Insert(PyWideStringList *list,
302 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100303{
Victor Stinner3842f292019-08-23 16:57:54 +0100304 Py_ssize_t len = list->length;
305 if (len == PY_SSIZE_T_MAX) {
Min ho Kim96e12d52019-07-22 06:12:33 +1000306 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200307 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100308 }
Victor Stinner3842f292019-08-23 16:57:54 +0100309 if (index < 0) {
310 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
311 }
312 if (index > len) {
313 index = len;
314 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100315
Victor Stinner74f65682019-03-15 15:08:05 +0100316 wchar_t *item2 = _PyMem_RawWcsdup(item);
317 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200318 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100319 }
Victor Stinner74f65682019-03-15 15:08:05 +0100320
Victor Stinner3842f292019-08-23 16:57:54 +0100321 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100322 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
323 if (items2 == NULL) {
324 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200325 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100326 }
327
Victor Stinner3842f292019-08-23 16:57:54 +0100328 if (index < len) {
329 memmove(&items2[index + 1],
330 &items2[index],
331 (len - index) * sizeof(items2[0]));
332 }
333
334 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100335 list->items = items2;
336 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200337 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100338}
339
340
Victor Stinner331a6a52019-05-27 16:39:22 +0200341PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100342PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
343{
344 return PyWideStringList_Insert(list, list->length, item);
345}
346
347
348PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200349_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100350{
351 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200352 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
353 if (_PyStatus_EXCEPTION(status)) {
354 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100355 }
356 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200357 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100358}
359
360
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100361static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200362_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100363{
364 for (Py_ssize_t i = 0; i < list->length; i++) {
365 if (wcscmp(list->items[i], item) == 0) {
366 return 1;
367 }
368 }
369 return 0;
370}
371
372
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100373PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200374_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100375{
Victor Stinner331a6a52019-05-27 16:39:22 +0200376 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100377
Victor Stinner74f65682019-03-15 15:08:05 +0100378 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100379 if (pylist == NULL) {
380 return NULL;
381 }
382
Victor Stinner74f65682019-03-15 15:08:05 +0100383 for (Py_ssize_t i = 0; i < list->length; i++) {
384 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
385 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100386 Py_DECREF(pylist);
387 return NULL;
388 }
Victor Stinner74f65682019-03-15 15:08:05 +0100389 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100390 }
391 return pylist;
392}
393
394
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100395/* --- Py_SetStandardStreamEncoding() ----------------------------- */
396
Victor Stinner124b9eb2018-08-29 01:29:06 +0200397/* Helper to allow an embedding application to override the normal
398 * mechanism that attempts to figure out an appropriate IO encoding
399 */
400
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200401static char *_Py_StandardStreamEncoding = NULL;
402static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200403
404int
405Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
406{
407 if (Py_IsInitialized()) {
408 /* This is too late to have any effect */
409 return -1;
410 }
411
412 int res = 0;
413
414 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
415 but Py_Initialize() can change the allocator. Use a known allocator
416 to be able to release the memory later. */
417 PyMemAllocatorEx old_alloc;
418 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
419
420 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
421 * initialised yet.
422 *
423 * However, the raw memory allocators are initialised appropriately
424 * as C static variables, so _PyMem_RawStrdup is OK even though
425 * Py_Initialize hasn't been called yet.
426 */
427 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200428 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200429 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
430 if (!_Py_StandardStreamEncoding) {
431 res = -2;
432 goto done;
433 }
434 }
435 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200436 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200437 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
438 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200439 PyMem_RawFree(_Py_StandardStreamEncoding);
440 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200441 res = -3;
442 goto done;
443 }
444 }
445#ifdef MS_WINDOWS
446 if (_Py_StandardStreamEncoding) {
447 /* Overriding the stream encoding implies legacy streams */
448 Py_LegacyWindowsStdioFlag = 1;
449 }
450#endif
451
452done:
453 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
454
455 return res;
456}
457
458
459void
460_Py_ClearStandardStreamEncoding(void)
461{
462 /* Use the same allocator than Py_SetStandardStreamEncoding() */
463 PyMemAllocatorEx old_alloc;
464 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
465
466 /* We won't need them anymore. */
467 if (_Py_StandardStreamEncoding) {
468 PyMem_RawFree(_Py_StandardStreamEncoding);
469 _Py_StandardStreamEncoding = NULL;
470 }
471 if (_Py_StandardStreamErrors) {
472 PyMem_RawFree(_Py_StandardStreamErrors);
473 _Py_StandardStreamErrors = NULL;
474 }
475
476 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
477}
478
479
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100480/* --- Py_GetArgcArgv() ------------------------------------------- */
481
482/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200483static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100484
485
486void
487_Py_ClearArgcArgv(void)
488{
489 PyMemAllocatorEx old_alloc;
490 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
491
Victor Stinner331a6a52019-05-27 16:39:22 +0200492 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100493
494 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
495}
496
497
Victor Stinner4fffd382019-03-06 01:44:31 +0100498static int
Victor Stinner74f65682019-03-15 15:08:05 +0100499_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100500{
Victor Stinner331a6a52019-05-27 16:39:22 +0200501 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100502 int res;
503
504 PyMemAllocatorEx old_alloc;
505 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
506
Victor Stinner331a6a52019-05-27 16:39:22 +0200507 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100508
509 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
510 return res;
511}
512
513
514/* Make the *original* argc/argv available to other modules.
515 This is rare, but it is needed by the secureware extension. */
516void
517Py_GetArgcArgv(int *argc, wchar_t ***argv)
518{
Victor Stinner74f65682019-03-15 15:08:05 +0100519 *argc = (int)orig_argv.length;
520 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100521}
522
523
Victor Stinner331a6a52019-05-27 16:39:22 +0200524/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100525
526#define DECODE_LOCALE_ERR(NAME, LEN) \
527 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200528 ? _PyStatus_ERR("cannot decode " NAME) \
529 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100530
Victor Stinner441b10c2019-09-28 04:28:35 +0200531
Victor Stinner6c785c02018-08-01 17:56:14 +0200532/* Free memory allocated in config, but don't clear all attributes */
533void
Victor Stinner331a6a52019-05-27 16:39:22 +0200534PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200535{
536#define CLEAR(ATTR) \
537 do { \
538 PyMem_RawFree(ATTR); \
539 ATTR = NULL; \
540 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200541
542 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200543 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200544 CLEAR(config->home);
545 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200546
Victor Stinner331a6a52019-05-27 16:39:22 +0200547 _PyWideStringList_Clear(&config->argv);
548 _PyWideStringList_Clear(&config->warnoptions);
549 _PyWideStringList_Clear(&config->xoptions);
550 _PyWideStringList_Clear(&config->module_search_paths);
551 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200552
553 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700554 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200555 CLEAR(config->prefix);
556 CLEAR(config->base_prefix);
557 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200558 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200559
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200560 CLEAR(config->filesystem_encoding);
561 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200562 CLEAR(config->stdio_encoding);
563 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100564 CLEAR(config->run_command);
565 CLEAR(config->run_module);
566 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400567 CLEAR(config->check_hash_pycs_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200568#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200569}
570
571
Victor Stinner8462a492019-10-01 12:06:16 +0200572void
Victor Stinner331a6a52019-05-27 16:39:22 +0200573_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200574{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200575 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200576
Victor Stinner022be022019-05-22 23:58:50 +0200577 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200578 config->isolated = -1;
579 config->use_environment = -1;
580 config->dev_mode = -1;
581 config->install_signal_handlers = 1;
582 config->use_hash_seed = -1;
583 config->faulthandler = -1;
584 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200585 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200586 config->parse_argv = 0;
587 config->site_import = -1;
588 config->bytes_warning = -1;
589 config->inspect = -1;
590 config->interactive = -1;
591 config->optimization_level = -1;
592 config->parser_debug= -1;
593 config->write_bytecode = -1;
594 config->verbose = -1;
595 config->quiet = -1;
596 config->user_site_directory = -1;
597 config->configure_c_stdio = 0;
598 config->buffered_stdio = -1;
599 config->_install_importlib = 1;
600 config->check_hash_pycs_mode = NULL;
601 config->pathconfig_warnings = -1;
602 config->_init_main = 1;
603#ifdef MS_WINDOWS
604 config->legacy_windows_stdio = -1;
605#endif
606}
607
608
Victor Stinner8462a492019-10-01 12:06:16 +0200609static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200610config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200611{
Victor Stinner8462a492019-10-01 12:06:16 +0200612 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200613
614 config->isolated = 0;
615 config->use_environment = 1;
616 config->site_import = 1;
617 config->bytes_warning = 0;
618 config->inspect = 0;
619 config->interactive = 0;
620 config->optimization_level = 0;
621 config->parser_debug= 0;
622 config->write_bytecode = 1;
623 config->verbose = 0;
624 config->quiet = 0;
625 config->user_site_directory = 1;
626 config->buffered_stdio = 1;
627 config->pathconfig_warnings = 1;
628#ifdef MS_WINDOWS
629 config->legacy_windows_stdio = 0;
630#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200631}
632
633
Victor Stinner8462a492019-10-01 12:06:16 +0200634void
Victor Stinner331a6a52019-05-27 16:39:22 +0200635PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200636{
Victor Stinner8462a492019-10-01 12:06:16 +0200637 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200638
Victor Stinner022be022019-05-22 23:58:50 +0200639 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200640 config->configure_c_stdio = 1;
641 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200642}
643
644
Victor Stinner8462a492019-10-01 12:06:16 +0200645void
Victor Stinner331a6a52019-05-27 16:39:22 +0200646PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200647{
Victor Stinner8462a492019-10-01 12:06:16 +0200648 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200649
Victor Stinner022be022019-05-22 23:58:50 +0200650 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200651 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200652 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200653 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200654 config->dev_mode = 0;
655 config->install_signal_handlers = 0;
656 config->use_hash_seed = 0;
657 config->faulthandler = 0;
658 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200659 config->pathconfig_warnings = 0;
660#ifdef MS_WINDOWS
661 config->legacy_windows_stdio = 0;
662#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200663}
664
665
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200666/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200667PyStatus
668PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200669{
Victor Stinner331a6a52019-05-27 16:39:22 +0200670 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
671 if (_PyStatus_EXCEPTION(status)) {
672 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200673 }
674
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200675 wchar_t *str2;
676 if (str != NULL) {
677 str2 = _PyMem_RawWcsdup(str);
678 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200679 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200680 }
681 }
682 else {
683 str2 = NULL;
684 }
685 PyMem_RawFree(*config_str);
686 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200687 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200688}
689
690
Victor Stinner331a6a52019-05-27 16:39:22 +0200691static PyStatus
692config_set_bytes_string(PyConfig *config, wchar_t **config_str,
693 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200694{
Victor Stinner331a6a52019-05-27 16:39:22 +0200695 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
696 if (_PyStatus_EXCEPTION(status)) {
697 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400698 }
699
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200700 wchar_t *str2;
701 if (str != NULL) {
702 size_t len;
703 str2 = Py_DecodeLocale(str, &len);
704 if (str2 == NULL) {
705 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200706 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200707 }
708 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200709 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200710 }
711 }
712 }
713 else {
714 str2 = NULL;
715 }
716 PyMem_RawFree(*config_str);
717 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200718 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200719}
720
721
Victor Stinner331a6a52019-05-27 16:39:22 +0200722#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
723 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400724
725
Victor Stinner70005ac2019-05-02 15:25:34 -0400726/* Decode str using Py_DecodeLocale() and set the result into *config_str.
727 Pre-initialize Python if needed to ensure that encodings are properly
728 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200729PyStatus
730PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200731 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400732{
Victor Stinner331a6a52019-05-27 16:39:22 +0200733 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400734}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200735
736
Victor Stinner331a6a52019-05-27 16:39:22 +0200737PyStatus
738_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200739{
Victor Stinner331a6a52019-05-27 16:39:22 +0200740 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200741
Victor Stinner331a6a52019-05-27 16:39:22 +0200742 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200743
744#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200745#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200746 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200747 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
748 if (_PyStatus_EXCEPTION(status)) { \
749 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200750 } \
751 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100752#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200753 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200754 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200755 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200756 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200757 } while (0)
758
Victor Stinner6d1c4672019-05-20 11:02:00 +0200759 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100760 COPY_ATTR(isolated);
761 COPY_ATTR(use_environment);
762 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200763 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200764 COPY_ATTR(use_hash_seed);
765 COPY_ATTR(hash_seed);
766 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200767 COPY_ATTR(faulthandler);
768 COPY_ATTR(tracemalloc);
769 COPY_ATTR(import_time);
770 COPY_ATTR(show_ref_count);
771 COPY_ATTR(show_alloc_count);
772 COPY_ATTR(dump_refs);
773 COPY_ATTR(malloc_stats);
774
Victor Stinner124b9eb2018-08-29 01:29:06 +0200775 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200776 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200777 COPY_WSTR_ATTR(home);
778 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200779
Victor Stinnerae239f62019-05-16 17:02:56 +0200780 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100781 COPY_WSTRLIST(argv);
782 COPY_WSTRLIST(warnoptions);
783 COPY_WSTRLIST(xoptions);
784 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200785 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200786
Victor Stinner124b9eb2018-08-29 01:29:06 +0200787 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700788 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200789 COPY_WSTR_ATTR(prefix);
790 COPY_WSTR_ATTR(base_prefix);
791 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200792 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200793
Victor Stinner6c785c02018-08-01 17:56:14 +0200794 COPY_ATTR(site_import);
795 COPY_ATTR(bytes_warning);
796 COPY_ATTR(inspect);
797 COPY_ATTR(interactive);
798 COPY_ATTR(optimization_level);
799 COPY_ATTR(parser_debug);
800 COPY_ATTR(write_bytecode);
801 COPY_ATTR(verbose);
802 COPY_ATTR(quiet);
803 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200804 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200805 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400806 COPY_WSTR_ATTR(filesystem_encoding);
807 COPY_WSTR_ATTR(filesystem_errors);
808 COPY_WSTR_ATTR(stdio_encoding);
809 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200810#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200811 COPY_ATTR(legacy_windows_stdio);
812#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100813 COPY_ATTR(skip_source_first_line);
814 COPY_WSTR_ATTR(run_command);
815 COPY_WSTR_ATTR(run_module);
816 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400817 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200818 COPY_ATTR(pathconfig_warnings);
819 COPY_ATTR(_init_main);
Victor Stinner6c785c02018-08-01 17:56:14 +0200820
821#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200822#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200823#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200824 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200825}
826
827
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100828static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200829config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100830{
831 PyObject *dict;
832
833 dict = PyDict_New();
834 if (dict == NULL) {
835 return NULL;
836 }
837
838#define SET_ITEM(KEY, EXPR) \
839 do { \
840 PyObject *obj = (EXPR); \
841 if (obj == NULL) { \
842 goto fail; \
843 } \
844 int res = PyDict_SetItemString(dict, (KEY), obj); \
845 Py_DECREF(obj); \
846 if (res < 0) { \
847 goto fail; \
848 } \
849 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100850#define SET_ITEM_INT(ATTR) \
851 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
852#define SET_ITEM_UINT(ATTR) \
853 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100854#define FROM_WSTRING(STR) \
855 ((STR != NULL) ? \
856 PyUnicode_FromWideChar(STR, -1) \
857 : (Py_INCREF(Py_None), Py_None))
858#define SET_ITEM_WSTR(ATTR) \
859 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
860#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200861 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100862
Victor Stinner6d1c4672019-05-20 11:02:00 +0200863 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100864 SET_ITEM_INT(isolated);
865 SET_ITEM_INT(use_environment);
866 SET_ITEM_INT(dev_mode);
867 SET_ITEM_INT(install_signal_handlers);
868 SET_ITEM_INT(use_hash_seed);
869 SET_ITEM_UINT(hash_seed);
870 SET_ITEM_INT(faulthandler);
871 SET_ITEM_INT(tracemalloc);
872 SET_ITEM_INT(import_time);
873 SET_ITEM_INT(show_ref_count);
874 SET_ITEM_INT(show_alloc_count);
875 SET_ITEM_INT(dump_refs);
876 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400877 SET_ITEM_WSTR(filesystem_encoding);
878 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100879 SET_ITEM_WSTR(pycache_prefix);
880 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200881 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100882 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100883 SET_ITEM_WSTRLIST(xoptions);
884 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200885 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100886 SET_ITEM_WSTR(home);
887 SET_ITEM_WSTRLIST(module_search_paths);
888 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700889 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100890 SET_ITEM_WSTR(prefix);
891 SET_ITEM_WSTR(base_prefix);
892 SET_ITEM_WSTR(exec_prefix);
893 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100894 SET_ITEM_INT(site_import);
895 SET_ITEM_INT(bytes_warning);
896 SET_ITEM_INT(inspect);
897 SET_ITEM_INT(interactive);
898 SET_ITEM_INT(optimization_level);
899 SET_ITEM_INT(parser_debug);
900 SET_ITEM_INT(write_bytecode);
901 SET_ITEM_INT(verbose);
902 SET_ITEM_INT(quiet);
903 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200904 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100905 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400906 SET_ITEM_WSTR(stdio_encoding);
907 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100908#ifdef MS_WINDOWS
909 SET_ITEM_INT(legacy_windows_stdio);
910#endif
911 SET_ITEM_INT(skip_source_first_line);
912 SET_ITEM_WSTR(run_command);
913 SET_ITEM_WSTR(run_module);
914 SET_ITEM_WSTR(run_filename);
915 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400916 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200917 SET_ITEM_INT(pathconfig_warnings);
918 SET_ITEM_INT(_init_main);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100919
920 return dict;
921
922fail:
923 Py_DECREF(dict);
924 return NULL;
925
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100926#undef FROM_WSTRING
927#undef SET_ITEM
928#undef SET_ITEM_INT
929#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100930#undef SET_ITEM_WSTR
931#undef SET_ITEM_WSTRLIST
932}
933
934
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100935static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200936config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200937{
Victor Stinner20004952019-03-26 02:31:11 +0100938 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200939}
940
941
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100942/* Get a copy of the environment variable as wchar_t*.
943 Return 0 on success, but *dest can be NULL.
944 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200945static PyStatus
946config_get_env_dup(PyConfig *config,
947 wchar_t **dest,
948 wchar_t *wname, char *name,
949 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200950{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200951 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100952 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200953
Victor Stinner20004952019-03-26 02:31:11 +0100954 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200955 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200956 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200957 }
958
959#ifdef MS_WINDOWS
960 const wchar_t *var = _wgetenv(wname);
961 if (!var || var[0] == '\0') {
962 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200963 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200964 }
965
Victor Stinner331a6a52019-05-27 16:39:22 +0200966 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +0200967#else
968 const char *var = getenv(name);
969 if (!var || var[0] == '\0') {
970 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200971 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200972 }
973
Victor Stinner331a6a52019-05-27 16:39:22 +0200974 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +0200975#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200976}
977
978
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200979#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200980 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200981
982
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100983static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200984config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200985{
Victor Stinner022be022019-05-22 23:58:50 +0200986 if (config->_config_init != _PyConfig_INIT_COMPAT) {
987 /* Python and Isolated configuration ignore global variables */
988 return;
989 }
990
Victor Stinner6c785c02018-08-01 17:56:14 +0200991#define COPY_FLAG(ATTR, VALUE) \
992 if (config->ATTR == -1) { \
993 config->ATTR = VALUE; \
994 }
995#define COPY_NOT_FLAG(ATTR, VALUE) \
996 if (config->ATTR == -1) { \
997 config->ATTR = !(VALUE); \
998 }
999
Victor Stinner20004952019-03-26 02:31:11 +01001000 COPY_FLAG(isolated, Py_IsolatedFlag);
1001 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001002 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1003 COPY_FLAG(inspect, Py_InspectFlag);
1004 COPY_FLAG(interactive, Py_InteractiveFlag);
1005 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1006 COPY_FLAG(parser_debug, Py_DebugFlag);
1007 COPY_FLAG(verbose, Py_VerboseFlag);
1008 COPY_FLAG(quiet, Py_QuietFlag);
1009#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001010 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1011#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001012 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001013
Victor Stinner6c785c02018-08-01 17:56:14 +02001014 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1015 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1016 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1017 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1018
Victor Stinner6c785c02018-08-01 17:56:14 +02001019#undef COPY_FLAG
1020#undef COPY_NOT_FLAG
1021}
1022
1023
1024/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001025static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001026config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001027{
1028#define COPY_FLAG(ATTR, VAR) \
1029 if (config->ATTR != -1) { \
1030 VAR = config->ATTR; \
1031 }
1032#define COPY_NOT_FLAG(ATTR, VAR) \
1033 if (config->ATTR != -1) { \
1034 VAR = !config->ATTR; \
1035 }
1036
Victor Stinner20004952019-03-26 02:31:11 +01001037 COPY_FLAG(isolated, Py_IsolatedFlag);
1038 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001039 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1040 COPY_FLAG(inspect, Py_InspectFlag);
1041 COPY_FLAG(interactive, Py_InteractiveFlag);
1042 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1043 COPY_FLAG(parser_debug, Py_DebugFlag);
1044 COPY_FLAG(verbose, Py_VerboseFlag);
1045 COPY_FLAG(quiet, Py_QuietFlag);
1046#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001047 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1048#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001049 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001050
Victor Stinner6c785c02018-08-01 17:56:14 +02001051 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1052 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1053 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1054 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1055
Victor Stinner6c785c02018-08-01 17:56:14 +02001056 /* Random or non-zero hash seed */
1057 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1058 config->hash_seed != 0);
1059
1060#undef COPY_FLAG
1061#undef COPY_NOT_FLAG
1062}
1063
1064
1065/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1066 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001067static PyStatus
1068config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001069{
Victor Stinner331a6a52019-05-27 16:39:22 +02001070 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001071
Victor Stinner6c785c02018-08-01 17:56:14 +02001072 /* If Py_SetProgramName() was called, use its value */
1073 const wchar_t *program_name = _Py_path_config.program_name;
1074 if (program_name != NULL) {
1075 config->program_name = _PyMem_RawWcsdup(program_name);
1076 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001077 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001078 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001079 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001080 }
1081
1082#ifdef __APPLE__
1083 /* On MacOS X, when the Python interpreter is embedded in an
1084 application bundle, it gets executed by a bootstrapping script
1085 that does os.execve() with an argv[0] that's different from the
1086 actual Python executable. This is needed to keep the Finder happy,
1087 or rather, to work around Apple's overly strict requirements of
1088 the process name. However, we still need a usable sys.executable,
1089 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001090 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001091 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001092 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001093 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001094 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1095 "PYTHONEXECUTABLE environment variable");
1096 if (_PyStatus_EXCEPTION(status)) {
1097 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001098 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001099 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001100 }
1101#ifdef WITH_NEXT_FRAMEWORK
1102 else {
1103 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1104 if (pyvenv_launcher && *pyvenv_launcher) {
1105 /* Used by Mac/Tools/pythonw.c to forward
1106 * the argv0 of the stub executable
1107 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001108 status = CONFIG_SET_BYTES_STR(config,
1109 &config->program_name,
1110 pyvenv_launcher,
1111 "__PYVENV_LAUNCHER__ environment variable");
1112 if (_PyStatus_EXCEPTION(status)) {
1113 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001114 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001115 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001116 }
1117 }
1118#endif /* WITH_NEXT_FRAMEWORK */
1119#endif /* __APPLE__ */
1120
Victor Stinnerfed02e12019-05-17 11:12:09 +02001121 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001122 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001123 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1124 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1125 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001126 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001127 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001128 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001129 }
1130
Victor Stinnerfed02e12019-05-17 11:12:09 +02001131 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001132#ifdef MS_WINDOWS
1133 const wchar_t *default_program_name = L"python";
1134#else
1135 const wchar_t *default_program_name = L"python3";
1136#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001137 status = PyConfig_SetString(config, &config->program_name,
1138 default_program_name);
1139 if (_PyStatus_EXCEPTION(status)) {
1140 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001141 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001142 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001143}
1144
Victor Stinner331a6a52019-05-27 16:39:22 +02001145static PyStatus
1146config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001147{
1148 assert(config->executable == NULL);
1149
1150 /* If Py_SetProgramFullPath() was called, use its value */
1151 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1152 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001153 PyStatus status = PyConfig_SetString(config,
1154 &config->executable,
1155 program_full_path);
1156 if (_PyStatus_EXCEPTION(status)) {
1157 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001158 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001159 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001160 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001161 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001162}
Victor Stinner6c785c02018-08-01 17:56:14 +02001163
Victor Stinner4fffd382019-03-06 01:44:31 +01001164
Victor Stinner6c785c02018-08-01 17:56:14 +02001165static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001166config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001167{
Victor Stinner74f65682019-03-15 15:08:05 +01001168 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001169}
1170
1171
Victor Stinner331a6a52019-05-27 16:39:22 +02001172static PyStatus
1173config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001174{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001175 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001176
1177 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001178 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001179 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001180 PyStatus status = PyConfig_SetString(config, &config->home, home);
1181 if (_PyStatus_EXCEPTION(status)) {
1182 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001183 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001184 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001185 }
1186
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001187 return CONFIG_GET_ENV_DUP(config, &config->home,
1188 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001189}
1190
1191
Victor Stinner331a6a52019-05-27 16:39:22 +02001192static PyStatus
1193config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001194{
Victor Stinner331a6a52019-05-27 16:39:22 +02001195 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001196
1197 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1198 /* Convert a text seed to a numeric one */
1199 if (seed_text && strcmp(seed_text, "random") != 0) {
1200 const char *endptr = seed_text;
1201 unsigned long seed;
1202 errno = 0;
1203 seed = strtoul(seed_text, (char **)&endptr, 10);
1204 if (*endptr != '\0'
1205 || seed > 4294967295UL
1206 || (errno == ERANGE && seed == ULONG_MAX))
1207 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001208 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001209 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001210 }
1211 /* Use a specific hash */
1212 config->use_hash_seed = 1;
1213 config->hash_seed = seed;
1214 }
1215 else {
1216 /* Use a random hash */
1217 config->use_hash_seed = 0;
1218 config->hash_seed = 0;
1219 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001220 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001221}
1222
1223
Victor Stinner6c785c02018-08-01 17:56:14 +02001224static int
1225config_wstr_to_int(const wchar_t *wstr, int *result)
1226{
1227 const wchar_t *endptr = wstr;
1228 errno = 0;
1229 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1230 if (*endptr != '\0' || errno == ERANGE) {
1231 return -1;
1232 }
1233 if (value < INT_MIN || value > INT_MAX) {
1234 return -1;
1235 }
1236
1237 *result = (int)value;
1238 return 0;
1239}
1240
1241
Victor Stinner331a6a52019-05-27 16:39:22 +02001242static PyStatus
1243config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001244{
Victor Stinner331a6a52019-05-27 16:39:22 +02001245 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001246 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001247
Victor Stinner6c785c02018-08-01 17:56:14 +02001248 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001249 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1250 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1251 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1252 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001253
1254 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001255 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001256 if (dont_write_bytecode) {
1257 config->write_bytecode = 0;
1258 }
1259
1260 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001261 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001262 if (no_user_site_directory) {
1263 config->user_site_directory = 0;
1264 }
1265
1266 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001267 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001268 if (unbuffered_stdio) {
1269 config->buffered_stdio = 0;
1270 }
1271
1272#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001273 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001274 "PYTHONLEGACYWINDOWSSTDIO");
1275#endif
1276
Victor Stinner331a6a52019-05-27 16:39:22 +02001277 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001278 config->dump_refs = 1;
1279 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001280 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001281 config->malloc_stats = 1;
1282 }
1283
Victor Stinner331a6a52019-05-27 16:39:22 +02001284 if (config->pythonpath_env == NULL) {
1285 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1286 L"PYTHONPATH", "PYTHONPATH");
1287 if (_PyStatus_EXCEPTION(status)) {
1288 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001289 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001290 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001291
1292 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001293 status = config_init_hash_seed(config);
1294 if (_PyStatus_EXCEPTION(status)) {
1295 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001296 }
1297 }
1298
Victor Stinner331a6a52019-05-27 16:39:22 +02001299 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001300}
1301
1302
Victor Stinner331a6a52019-05-27 16:39:22 +02001303static PyStatus
1304config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001305{
1306 int nframe;
1307 int valid;
1308
Victor Stinner331a6a52019-05-27 16:39:22 +02001309 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001310 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001311 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001312 valid = (nframe >= 0);
1313 }
1314 else {
1315 valid = 0;
1316 }
1317 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001318 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001319 }
1320 config->tracemalloc = nframe;
1321 }
1322
1323 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1324 if (xoption) {
1325 const wchar_t *sep = wcschr(xoption, L'=');
1326 if (sep) {
1327 if (!config_wstr_to_int(sep + 1, &nframe)) {
1328 valid = (nframe >= 0);
1329 }
1330 else {
1331 valid = 0;
1332 }
1333 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001334 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1335 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001336 }
1337 }
1338 else {
1339 /* -X tracemalloc behaves as -X tracemalloc=1 */
1340 nframe = 1;
1341 }
1342 config->tracemalloc = nframe;
1343 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001344 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001345}
1346
1347
Victor Stinner331a6a52019-05-27 16:39:22 +02001348static PyStatus
1349config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001350{
1351 assert(config->pycache_prefix == NULL);
1352
1353 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1354 if (xoption) {
1355 const wchar_t *sep = wcschr(xoption, L'=');
1356 if (sep && wcslen(sep) > 1) {
1357 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1358 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001359 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001360 }
1361 }
1362 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001363 // PYTHONPYCACHEPREFIX env var ignored
1364 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001365 config->pycache_prefix = NULL;
1366 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001367 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001368 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001369
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001370 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1371 L"PYTHONPYCACHEPREFIX",
1372 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001373}
1374
1375
Victor Stinner331a6a52019-05-27 16:39:22 +02001376static PyStatus
1377config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001378{
1379 /* More complex options configured by env var and -X option */
1380 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001381 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001382 || config_get_xoption(config, L"faulthandler")) {
1383 config->faulthandler = 1;
1384 }
1385 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001386 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001387 || config_get_xoption(config, L"importtime")) {
1388 config->import_time = 1;
1389 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001390
Victor Stinner331a6a52019-05-27 16:39:22 +02001391 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001392 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001393 status = config_init_tracemalloc(config);
1394 if (_PyStatus_EXCEPTION(status)) {
1395 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001396 }
1397 }
1398
1399 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001400 status = config_init_pycache_prefix(config);
1401 if (_PyStatus_EXCEPTION(status)) {
1402 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001403 }
1404 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001405 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001406}
1407
1408
Victor Stinner709d23d2019-05-02 14:56:30 -04001409static const wchar_t *
Victor Stinner331a6a52019-05-27 16:39:22 +02001410config_get_stdio_errors(const PyConfig *config)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001411{
1412#ifndef MS_WINDOWS
1413 const char *loc = setlocale(LC_CTYPE, NULL);
1414 if (loc != NULL) {
1415 /* surrogateescape is the default in the legacy C and POSIX locales */
1416 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001417 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001418 }
1419
1420#ifdef PY_COERCE_C_LOCALE
1421 /* surrogateescape is the default in locale coercion target locales */
1422 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001423 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001424 }
1425#endif
1426 }
1427
Victor Stinner709d23d2019-05-02 14:56:30 -04001428 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001429#else
1430 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001431 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001432#endif
1433}
1434
1435
Victor Stinner331a6a52019-05-27 16:39:22 +02001436static PyStatus
1437config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001438{
1439#ifdef MS_WINDOWS
1440 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001441 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001442 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001443#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001444 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001445#else
1446 const char *encoding = nl_langinfo(CODESET);
1447 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001448 return _PyStatus_ERR("failed to get the locale encoding: "
1449 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001450 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001451 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001452 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001453 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001454 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001455#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001456}
1457
1458
Victor Stinner331a6a52019-05-27 16:39:22 +02001459static PyStatus
1460config_init_stdio_encoding(PyConfig *config,
1461 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001462{
Victor Stinner331a6a52019-05-27 16:39:22 +02001463 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001464
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001465 /* If Py_SetStandardStreamEncoding() have been called, use these
1466 parameters. */
1467 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001468 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1469 _Py_StandardStreamEncoding,
1470 "_Py_StandardStreamEncoding");
1471 if (_PyStatus_EXCEPTION(status)) {
1472 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001473 }
1474 }
1475
1476 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001477 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1478 _Py_StandardStreamErrors,
1479 "_Py_StandardStreamErrors");
1480 if (_PyStatus_EXCEPTION(status)) {
1481 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001482 }
1483 }
1484
1485 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001486 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001487 }
1488
1489 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001490 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001491 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001492 char *pythonioencoding = _PyMem_RawStrdup(opt);
1493 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001494 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001495 }
1496
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001497 char *errors = strchr(pythonioencoding, ':');
1498 if (errors) {
1499 *errors = '\0';
1500 errors++;
1501 if (!errors[0]) {
1502 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001503 }
1504 }
1505
1506 /* Does PYTHONIOENCODING contain an encoding? */
1507 if (pythonioencoding[0]) {
1508 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001509 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1510 pythonioencoding,
1511 "PYTHONIOENCODING environment variable");
1512 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001513 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001514 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001515 }
1516 }
1517
1518 /* If the encoding is set but not the error handler,
1519 use "strict" error handler by default.
1520 PYTHONIOENCODING=latin1 behaves as
1521 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001522 if (!errors) {
1523 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001524 }
1525 }
1526
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001527 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001528 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1529 errors,
1530 "PYTHONIOENCODING environment variable");
1531 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001532 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001533 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001534 }
1535 }
1536
1537 PyMem_RawFree(pythonioencoding);
1538 }
1539
1540 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001541 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001542 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001543 status = PyConfig_SetString(config, &config->stdio_encoding,
1544 L"utf-8");
1545 if (_PyStatus_EXCEPTION(status)) {
1546 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001547 }
1548 }
1549 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001550 status = PyConfig_SetString(config, &config->stdio_errors,
1551 L"surrogateescape");
1552 if (_PyStatus_EXCEPTION(status)) {
1553 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001554 }
1555 }
1556 }
1557
1558 /* Choose the default error handler based on the current locale. */
1559 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001560 status = config_get_locale_encoding(config, &config->stdio_encoding);
1561 if (_PyStatus_EXCEPTION(status)) {
1562 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001563 }
1564 }
1565 if (config->stdio_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001566 const wchar_t *errors = config_get_stdio_errors(config);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001567 assert(errors != NULL);
1568
Victor Stinner331a6a52019-05-27 16:39:22 +02001569 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1570 if (_PyStatus_EXCEPTION(status)) {
1571 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001572 }
1573 }
1574
Victor Stinner331a6a52019-05-27 16:39:22 +02001575 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001576}
1577
1578
Victor Stinner331a6a52019-05-27 16:39:22 +02001579static PyStatus
1580config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001581{
Victor Stinner331a6a52019-05-27 16:39:22 +02001582 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001583
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001584 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001585#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001586 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001587#else
Victor Stinnere2510952019-05-02 11:28:57 -04001588
1589#ifdef MS_WINDOWS
1590 if (preconfig->legacy_windows_fs_encoding) {
1591 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001592 status = PyConfig_SetString(config, &config->filesystem_encoding,
1593 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001594 }
1595 else
1596#endif
Victor Stinner20004952019-03-26 02:31:11 +01001597 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001598 status = PyConfig_SetString(config, &config->filesystem_encoding,
1599 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001600 }
Victor Stinnere2510952019-05-02 11:28:57 -04001601#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001602 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001603 status = PyConfig_SetString(config, &config->filesystem_encoding,
1604 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001605 }
Victor Stinnere2510952019-05-02 11:28:57 -04001606#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001607 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001608#ifdef MS_WINDOWS
1609 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001610 status = PyConfig_SetString(config, &config->filesystem_encoding,
1611 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001612#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001613 status = config_get_locale_encoding(config,
1614 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001615#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001616 }
Victor Stinnere2510952019-05-02 11:28:57 -04001617#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001618
Victor Stinner331a6a52019-05-27 16:39:22 +02001619 if (_PyStatus_EXCEPTION(status)) {
1620 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001621 }
1622 }
1623
1624 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001625 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001626#ifdef MS_WINDOWS
1627 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001628 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001629 }
1630 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001631 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001632 }
1633#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001634 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001635#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001636 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1637 if (_PyStatus_EXCEPTION(status)) {
1638 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001639 }
1640 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001641 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001642}
1643
1644
Victor Stinner331a6a52019-05-27 16:39:22 +02001645static PyStatus
1646config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001647{
Victor Stinner331a6a52019-05-27 16:39:22 +02001648 PyStatus status;
1649 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001650
Victor Stinner20004952019-03-26 02:31:11 +01001651 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001652 status = config_read_env_vars(config);
1653 if (_PyStatus_EXCEPTION(status)) {
1654 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001655 }
1656 }
1657
1658 /* -X options */
1659 if (config_get_xoption(config, L"showrefcount")) {
1660 config->show_ref_count = 1;
1661 }
1662 if (config_get_xoption(config, L"showalloccount")) {
1663 config->show_alloc_count = 1;
1664 }
1665
Victor Stinner331a6a52019-05-27 16:39:22 +02001666 status = config_read_complex_options(config);
1667 if (_PyStatus_EXCEPTION(status)) {
1668 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001669 }
1670
Victor Stinner6c785c02018-08-01 17:56:14 +02001671 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001672 status = config_init_home(config);
1673 if (_PyStatus_EXCEPTION(status)) {
1674 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001675 }
1676 }
1677
Steve Dower177a41a2018-11-17 20:41:48 -08001678 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001679 status = config_init_executable(config);
1680 if (_PyStatus_EXCEPTION(status)) {
1681 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001682 }
1683 }
1684
Victor Stinner6c785c02018-08-01 17:56:14 +02001685 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001686 status = _PyConfig_InitPathConfig(config);
1687 if (_PyStatus_EXCEPTION(status)) {
1688 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001689 }
1690 }
1691
1692 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001693 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001694 if (config->faulthandler < 0) {
1695 config->faulthandler = 1;
1696 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001697 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001698 if (config->faulthandler < 0) {
1699 config->faulthandler = 0;
1700 }
1701 if (config->tracemalloc < 0) {
1702 config->tracemalloc = 0;
1703 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001704 if (config->use_hash_seed < 0) {
1705 config->use_hash_seed = 0;
1706 config->hash_seed = 0;
1707 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001708
Victor Stinner70fead22018-08-29 13:45:34 +02001709 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001710 status = config_init_fs_encoding(config, preconfig);
1711 if (_PyStatus_EXCEPTION(status)) {
1712 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001713 }
1714 }
1715
Victor Stinner331a6a52019-05-27 16:39:22 +02001716 status = config_init_stdio_encoding(config, preconfig);
1717 if (_PyStatus_EXCEPTION(status)) {
1718 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001719 }
1720
Victor Stinner62599762019-03-15 16:03:23 +01001721 if (config->argv.length < 1) {
1722 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001723 status = PyWideStringList_Append(&config->argv, L"");
1724 if (_PyStatus_EXCEPTION(status)) {
1725 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001726 }
1727 }
Victor Stinner870b0352019-05-17 03:15:12 +02001728
1729 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001730 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1731 L"default");
1732 if (_PyStatus_EXCEPTION(status)) {
1733 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001734 }
1735 }
1736
1737 if (config->configure_c_stdio < 0) {
1738 config->configure_c_stdio = 1;
1739 }
1740
Victor Stinner331a6a52019-05-27 16:39:22 +02001741 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001742}
Victor Stinner5ed69952018-11-06 15:59:52 +01001743
1744
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001745static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001746config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001747{
1748#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1749 /* don't translate newlines (\r\n <=> \n) */
1750 _setmode(fileno(stdin), O_BINARY);
1751 _setmode(fileno(stdout), O_BINARY);
1752 _setmode(fileno(stderr), O_BINARY);
1753#endif
1754
1755 if (!config->buffered_stdio) {
1756#ifdef HAVE_SETVBUF
1757 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1758 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1759 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1760#else /* !HAVE_SETVBUF */
1761 setbuf(stdin, (char *)NULL);
1762 setbuf(stdout, (char *)NULL);
1763 setbuf(stderr, (char *)NULL);
1764#endif /* !HAVE_SETVBUF */
1765 }
1766 else if (config->interactive) {
1767#ifdef MS_WINDOWS
1768 /* Doesn't have to have line-buffered -- use unbuffered */
1769 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1770 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1771#else /* !MS_WINDOWS */
1772#ifdef HAVE_SETVBUF
1773 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1774 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1775#endif /* HAVE_SETVBUF */
1776#endif /* !MS_WINDOWS */
1777 /* Leave stderr alone - it should be unbuffered anyway. */
1778 }
1779}
1780
1781
1782/* Write the configuration:
1783
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001784 - set Py_xxx global configuration variables
1785 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001786void
Victor Stinner331a6a52019-05-27 16:39:22 +02001787_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001788{
Victor Stinner331a6a52019-05-27 16:39:22 +02001789 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001790
1791 if (config->configure_c_stdio) {
1792 config_init_stdio(config);
1793 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001794
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001795 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001796 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001797 preconfig->isolated = config->isolated;
1798 preconfig->use_environment = config->use_environment;
1799 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001800}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001801
1802
Victor Stinner331a6a52019-05-27 16:39:22 +02001803/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001804
1805static void
Victor Stinner2f549082019-03-29 15:13:46 +01001806config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001807{
Victor Stinner2f549082019-03-29 15:13:46 +01001808 FILE *f = error ? stderr : stdout;
1809
1810 fprintf(f, usage_line, program);
1811 if (error)
1812 fprintf(f, "Try `python -h' for more information.\n");
1813 else {
1814 fputs(usage_1, f);
1815 fputs(usage_2, f);
1816 fputs(usage_3, f);
1817 fprintf(f, usage_4, (wint_t)DELIM);
1818 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1819 fputs(usage_6, f);
1820 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001821}
1822
1823
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001824/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001825static PyStatus
1826config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001827 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001828{
Victor Stinner331a6a52019-05-27 16:39:22 +02001829 PyStatus status;
1830 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001831 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001832 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001833
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001834 _PyOS_ResetGetOpt();
1835 do {
1836 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001837 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001838 if (c == EOF) {
1839 break;
1840 }
1841
1842 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001843 if (config->run_command == NULL) {
1844 /* -c is the last option; following arguments
1845 that look like options are left for the
1846 command to interpret. */
1847 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1848 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1849 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001850 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001851 }
1852 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1853 command[len - 2] = '\n';
1854 command[len - 1] = 0;
1855 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001856 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001857 break;
1858 }
1859
1860 if (c == 'm') {
1861 /* -m is the last option; following arguments
1862 that look like options are left for the
1863 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001864 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001865 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1866 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001867 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001868 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001869 }
1870 break;
1871 }
1872
1873 switch (c) {
1874 case 0:
1875 // Handle long option.
1876 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001877 if (wcscmp(_PyOS_optarg, L"always") == 0
1878 || wcscmp(_PyOS_optarg, L"never") == 0
1879 || wcscmp(_PyOS_optarg, L"default") == 0)
1880 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001881 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1882 _PyOS_optarg);
1883 if (_PyStatus_EXCEPTION(status)) {
1884 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001885 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001886 } else {
1887 fprintf(stderr, "--check-hash-based-pycs must be one of "
1888 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001889 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001890 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001891 }
1892 break;
1893
1894 case 'b':
1895 config->bytes_warning++;
1896 break;
1897
1898 case 'd':
1899 config->parser_debug++;
1900 break;
1901
1902 case 'i':
1903 config->inspect++;
1904 config->interactive++;
1905 break;
1906
Victor Stinner6dcb5422019-03-05 02:44:12 +01001907 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001908 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001909 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001910 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001911 break;
1912
1913 /* case 'J': reserved for Jython */
1914
1915 case 'O':
1916 config->optimization_level++;
1917 break;
1918
1919 case 'B':
1920 config->write_bytecode = 0;
1921 break;
1922
1923 case 's':
1924 config->user_site_directory = 0;
1925 break;
1926
1927 case 'S':
1928 config->site_import = 0;
1929 break;
1930
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001931 case 't':
1932 /* ignored for backwards compatibility */
1933 break;
1934
1935 case 'u':
1936 config->buffered_stdio = 0;
1937 break;
1938
1939 case 'v':
1940 config->verbose++;
1941 break;
1942
1943 case 'x':
1944 config->skip_source_first_line = 1;
1945 break;
1946
1947 case 'h':
1948 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001949 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001950 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001951
1952 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01001953 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001954 break;
1955
1956 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02001957 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
1958 if (_PyStatus_EXCEPTION(status)) {
1959 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001960 }
1961 break;
1962
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001963 case 'q':
1964 config->quiet++;
1965 break;
1966
1967 case 'R':
1968 config->use_hash_seed = 0;
1969 break;
1970
1971 /* This space reserved for other options */
1972
1973 default:
1974 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02001975 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001976 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001977 }
1978 } while (1);
1979
Victor Stinner2f549082019-03-29 15:13:46 +01001980 if (print_version) {
1981 printf("Python %s\n",
1982 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02001983 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01001984 }
1985
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001986 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01001987 && _PyOS_optind < argv->length
1988 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01001989 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001990 {
Victor Stinnerfa153762019-03-20 04:25:38 +01001991 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001992 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001993 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001994 }
1995 }
1996
1997 if (config->run_command != NULL || config->run_module != NULL) {
1998 /* Backup _PyOS_optind */
1999 _PyOS_optind--;
2000 }
2001
Victor Stinnerae239f62019-05-16 17:02:56 +02002002 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002003
Victor Stinner331a6a52019-05-27 16:39:22 +02002004 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002005}
2006
2007
2008#ifdef MS_WINDOWS
2009# define WCSTOK wcstok_s
2010#else
2011# define WCSTOK wcstok
2012#endif
2013
2014/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002015static PyStatus
2016config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002017{
Victor Stinner331a6a52019-05-27 16:39:22 +02002018 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002019 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2020 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002021 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002022 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002023 if (_PyStatus_EXCEPTION(status)) {
2024 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002025 }
2026
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002027 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002028 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002029 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002030 }
2031
2032
2033 wchar_t *warning, *context = NULL;
2034 for (warning = WCSTOK(env, L",", &context);
2035 warning != NULL;
2036 warning = WCSTOK(NULL, L",", &context))
2037 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002038 status = PyWideStringList_Append(warnoptions, warning);
2039 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002040 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002041 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002042 }
2043 }
2044 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002045 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002046}
2047
2048
Victor Stinner331a6a52019-05-27 16:39:22 +02002049static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002050warnoptions_append(PyConfig *config, PyWideStringList *options,
2051 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002052{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002053 /* config_init_warnoptions() add existing config warnoptions at the end:
2054 ensure that the new option is not already present in this list to
2055 prevent change the options order whne config_init_warnoptions() is
2056 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002057 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002058 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002059 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002060 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002061 if (_PyWideStringList_Find(options, option)) {
2062 /* Already present: do nothing */
2063 return _PyStatus_OK();
2064 }
2065 return PyWideStringList_Append(options, option);
2066}
2067
2068
2069static PyStatus
2070warnoptions_extend(PyConfig *config, PyWideStringList *options,
2071 const PyWideStringList *options2)
2072{
2073 const Py_ssize_t len = options2->length;
2074 wchar_t *const *items = options2->items;
2075
2076 for (Py_ssize_t i = 0; i < len; i++) {
2077 PyStatus status = warnoptions_append(config, options, items[i]);
2078 if (_PyStatus_EXCEPTION(status)) {
2079 return status;
2080 }
2081 }
2082 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002083}
2084
2085
Victor Stinner331a6a52019-05-27 16:39:22 +02002086static PyStatus
2087config_init_warnoptions(PyConfig *config,
2088 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002089 const PyWideStringList *env_warnoptions,
2090 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002091{
Victor Stinner331a6a52019-05-27 16:39:22 +02002092 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002093 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002094
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002095 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002096 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002097 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002098 * - PyConfig.dev_mode: "default" filter
2099 * - PYTHONWARNINGS environment variable
2100 * - '-W' command line options
2101 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2102 * "default::BytesWarning" or "error::BytesWarning" filter
2103 * - early PySys_AddWarnOption() calls
2104 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002105 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002106 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2107 * module works on the basis of "the most recently added filter will be
2108 * checked first", we add the lowest precedence entries first so that later
2109 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002110 */
2111
Victor Stinner20004952019-03-26 02:31:11 +01002112 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002113 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002114 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002115 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002116 }
2117 }
2118
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002119 status = warnoptions_extend(config, &options, env_warnoptions);
2120 if (_PyStatus_EXCEPTION(status)) {
2121 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002122 }
2123
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002124 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2125 if (_PyStatus_EXCEPTION(status)) {
2126 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002127 }
2128
2129 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2130 * don't even try to emit a warning, so we skip setting the filter in that
2131 * case.
2132 */
2133 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002134 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002135 if (config->bytes_warning> 1) {
2136 filter = L"error::BytesWarning";
2137 }
2138 else {
2139 filter = L"default::BytesWarning";
2140 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002141 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002142 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002143 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002144 }
2145 }
Victor Stinner120b7072019-08-23 18:03:08 +01002146
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002147 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002148 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002149 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002150 }
2151
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002152 /* Always add all PyConfig.warnoptions options */
2153 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2154 if (_PyStatus_EXCEPTION(status)) {
2155 goto error;
2156 }
2157
2158 _PyWideStringList_Clear(&config->warnoptions);
2159 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002160 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002161
2162error:
2163 _PyWideStringList_Clear(&options);
2164 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002165}
2166
2167
Victor Stinner331a6a52019-05-27 16:39:22 +02002168static PyStatus
2169config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002170{
Victor Stinner331a6a52019-05-27 16:39:22 +02002171 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002172 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002173
Victor Stinner74f65682019-03-15 15:08:05 +01002174 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002175 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002176 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002177 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2178 if (_PyStatus_EXCEPTION(status)) {
2179 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002180 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002181 }
2182 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002183 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002184 slice.length = cmdline_argv->length - opt_index;
2185 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002186 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2187 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002188 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002189 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002190 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002191
2192 wchar_t *arg0 = NULL;
2193 if (config->run_command != NULL) {
2194 /* Force sys.argv[0] = '-c' */
2195 arg0 = L"-c";
2196 }
2197 else if (config->run_module != NULL) {
2198 /* Force sys.argv[0] = '-m'*/
2199 arg0 = L"-m";
2200 }
Victor Stinner3939c322019-06-25 15:02:43 +02002201 else if (config->run_filename != NULL) {
2202 /* run_filename is converted to an absolute path: update argv */
2203 arg0 = config->run_filename;
2204 }
2205
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002206 if (arg0 != NULL) {
2207 arg0 = _PyMem_RawWcsdup(arg0);
2208 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002209 _PyWideStringList_Clear(&config_argv);
2210 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002211 }
2212
Victor Stinnerfa153762019-03-20 04:25:38 +01002213 PyMem_RawFree(config_argv.items[0]);
2214 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002215 }
2216
Victor Stinner331a6a52019-05-27 16:39:22 +02002217 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002218 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002219 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002220}
2221
2222
Victor Stinner331a6a52019-05-27 16:39:22 +02002223static PyStatus
2224core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002225{
Victor Stinner331a6a52019-05-27 16:39:22 +02002226 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002227
Victor Stinnercab5d072019-05-17 19:01:14 +02002228 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002229 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2230 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002231 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002232 }
2233
Victor Stinner331a6a52019-05-27 16:39:22 +02002234 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002235
2236 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2237 if (_PyStatus_EXCEPTION(status)) {
2238 return status;
2239 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002240
Victor Stinner331a6a52019-05-27 16:39:22 +02002241 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002242
Victor Stinner331a6a52019-05-27 16:39:22 +02002243 status = _PyPreCmdline_Read(precmdline, &preconfig);
2244 if (_PyStatus_EXCEPTION(status)) {
2245 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002246 }
2247
Victor Stinner331a6a52019-05-27 16:39:22 +02002248 status = _PyPreCmdline_SetConfig(precmdline, config);
2249 if (_PyStatus_EXCEPTION(status)) {
2250 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002251 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002252 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002253}
2254
2255
Victor Stinner3939c322019-06-25 15:02:43 +02002256/* Get run_filename absolute path */
2257static PyStatus
2258config_run_filename_abspath(PyConfig *config)
2259{
2260 if (!config->run_filename) {
2261 return _PyStatus_OK();
2262 }
2263
2264#ifndef MS_WINDOWS
2265 if (_Py_isabs(config->run_filename)) {
2266 /* path is already absolute */
2267 return _PyStatus_OK();
2268 }
2269#endif
2270
2271 wchar_t *abs_filename;
2272 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2273 /* failed to get the absolute path of the command line filename:
2274 ignore the error, keep the relative path */
2275 return _PyStatus_OK();
2276 }
2277 if (abs_filename == NULL) {
2278 return _PyStatus_NO_MEMORY();
2279 }
2280
2281 PyMem_RawFree(config->run_filename);
2282 config->run_filename = abs_filename;
2283 return _PyStatus_OK();
2284}
2285
2286
Victor Stinner331a6a52019-05-27 16:39:22 +02002287static PyStatus
2288config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002289{
Victor Stinner331a6a52019-05-27 16:39:22 +02002290 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002291 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2292 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2293 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002294
Victor Stinnerae239f62019-05-16 17:02:56 +02002295 if (config->parse_argv < 0) {
2296 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002297 }
Victor Stinner870b0352019-05-17 03:15:12 +02002298
Victor Stinnerfed02e12019-05-17 11:12:09 +02002299 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002300 status = config_init_program_name(config);
2301 if (_PyStatus_EXCEPTION(status)) {
2302 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002303 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002304 }
Victor Stinner2f549082019-03-29 15:13:46 +01002305
Victor Stinnerae239f62019-05-16 17:02:56 +02002306 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002307 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002308 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2309 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002310 goto done;
2311 }
2312
Victor Stinner3939c322019-06-25 15:02:43 +02002313 status = config_run_filename_abspath(config);
2314 if (_PyStatus_EXCEPTION(status)) {
2315 goto done;
2316 }
2317
Victor Stinner331a6a52019-05-27 16:39:22 +02002318 status = config_update_argv(config, opt_index);
2319 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002320 goto done;
2321 }
Victor Stinner2f549082019-03-29 15:13:46 +01002322 }
Victor Stinner3939c322019-06-25 15:02:43 +02002323 else {
2324 status = config_run_filename_abspath(config);
2325 if (_PyStatus_EXCEPTION(status)) {
2326 goto done;
2327 }
2328 }
Victor Stinner2f549082019-03-29 15:13:46 +01002329
Victor Stinner2f549082019-03-29 15:13:46 +01002330 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002331 status = config_init_env_warnoptions(config, &env_warnoptions);
2332 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002333 goto done;
2334 }
2335 }
2336
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002337 /* Handle early PySys_AddWarnOption() calls */
2338 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2339 if (_PyStatus_EXCEPTION(status)) {
2340 goto done;
2341 }
2342
Victor Stinner331a6a52019-05-27 16:39:22 +02002343 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002344 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002345 &env_warnoptions,
2346 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002347 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002348 goto done;
2349 }
2350
Victor Stinner331a6a52019-05-27 16:39:22 +02002351 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002352
2353done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002354 _PyWideStringList_Clear(&cmdline_warnoptions);
2355 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002356 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002357 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002358}
2359
2360
Victor Stinner331a6a52019-05-27 16:39:22 +02002361PyStatus
2362_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002363{
Victor Stinner331a6a52019-05-27 16:39:22 +02002364 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2365 if (_PyStatus_EXCEPTION(status)) {
2366 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002367 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002368
Victor Stinner5f38b842019-05-01 02:30:12 +02002369 return _PyArgv_AsWstrList(args, &config->argv);
2370}
2371
2372
Victor Stinner70005ac2019-05-02 15:25:34 -04002373/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2374 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002375PyStatus
2376PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002377{
2378 _PyArgv args = {
2379 .argc = argc,
2380 .use_bytes_argv = 1,
2381 .bytes_argv = argv,
2382 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002383 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002384}
2385
2386
Victor Stinner331a6a52019-05-27 16:39:22 +02002387PyStatus
2388PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002389{
2390 _PyArgv args = {
2391 .argc = argc,
2392 .use_bytes_argv = 0,
2393 .bytes_argv = NULL,
2394 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002395 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002396}
2397
2398
Victor Stinner36242fd2019-07-01 19:13:50 +02002399PyStatus
2400PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2401 Py_ssize_t length, wchar_t **items)
2402{
2403 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2404 if (_PyStatus_EXCEPTION(status)) {
2405 return status;
2406 }
2407
2408 PyWideStringList list2 = {.length = length, .items = items};
2409 if (_PyWideStringList_Copy(list, &list2) < 0) {
2410 return _PyStatus_NO_MEMORY();
2411 }
2412 return _PyStatus_OK();
2413}
2414
2415
Victor Stinner331a6a52019-05-27 16:39:22 +02002416/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002417
2418 * Command line arguments
2419 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002420 * Py_xxx global configuration variables
2421
2422 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002423PyStatus
2424PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002425{
Victor Stinner331a6a52019-05-27 16:39:22 +02002426 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002427 PyWideStringList orig_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002428
Victor Stinner331a6a52019-05-27 16:39:22 +02002429 status = _Py_PreInitializeFromConfig(config, NULL);
2430 if (_PyStatus_EXCEPTION(status)) {
2431 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002432 }
2433
Victor Stinner331a6a52019-05-27 16:39:22 +02002434 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002435
Victor Stinner331a6a52019-05-27 16:39:22 +02002436 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2437 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002438 }
2439
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002440 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002441 status = core_read_precmdline(config, &precmdline);
2442 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002443 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002444 }
2445
Victor Stinner870b0352019-05-17 03:15:12 +02002446 assert(config->isolated >= 0);
2447 if (config->isolated) {
2448 config->use_environment = 0;
2449 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002450 }
2451
Victor Stinner331a6a52019-05-27 16:39:22 +02002452 status = config_read_cmdline(config);
2453 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002454 goto done;
2455 }
2456
Victor Stinner120b7072019-08-23 18:03:08 +01002457 /* Handle early PySys_AddXOption() calls */
2458 status = _PySys_ReadPreinitXOptions(config);
2459 if (_PyStatus_EXCEPTION(status)) {
2460 goto done;
2461 }
2462
Victor Stinner331a6a52019-05-27 16:39:22 +02002463 status = config_read(config);
2464 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002465 goto done;
2466 }
2467
Victor Stinnercab5d072019-05-17 19:01:14 +02002468 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002469 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002470 goto done;
2471 }
2472
2473 /* Check config consistency */
2474 assert(config->isolated >= 0);
2475 assert(config->use_environment >= 0);
2476 assert(config->dev_mode >= 0);
2477 assert(config->install_signal_handlers >= 0);
2478 assert(config->use_hash_seed >= 0);
2479 assert(config->faulthandler >= 0);
2480 assert(config->tracemalloc >= 0);
2481 assert(config->site_import >= 0);
2482 assert(config->bytes_warning >= 0);
2483 assert(config->inspect >= 0);
2484 assert(config->interactive >= 0);
2485 assert(config->optimization_level >= 0);
2486 assert(config->parser_debug >= 0);
2487 assert(config->write_bytecode >= 0);
2488 assert(config->verbose >= 0);
2489 assert(config->quiet >= 0);
2490 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002491 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002492 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002493 assert(config->buffered_stdio >= 0);
2494 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002495 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002496 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2497 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002498 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2499 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2500 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002501 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002502 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002503 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002504 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002505 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002506 assert(config->prefix != NULL);
2507 assert(config->base_prefix != NULL);
2508 assert(config->exec_prefix != NULL);
2509 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002510 }
2511 assert(config->filesystem_encoding != NULL);
2512 assert(config->filesystem_errors != NULL);
2513 assert(config->stdio_encoding != NULL);
2514 assert(config->stdio_errors != NULL);
2515#ifdef MS_WINDOWS
2516 assert(config->legacy_windows_stdio >= 0);
2517#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002518 /* -c and -m options are exclusive */
2519 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002520 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002521 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002522 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002523
Victor Stinner331a6a52019-05-27 16:39:22 +02002524 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002525
2526done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002527 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002528 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002529 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002530}
Victor Stinner1075d162019-03-25 23:19:57 +01002531
2532
2533PyObject*
2534_Py_GetConfigsAsDict(void)
2535{
Victor Stinner331a6a52019-05-27 16:39:22 +02002536 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002537 PyObject *dict = NULL;
2538
Victor Stinner331a6a52019-05-27 16:39:22 +02002539 result = PyDict_New();
2540 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002541 goto error;
2542 }
2543
Victor Stinner331a6a52019-05-27 16:39:22 +02002544 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002545 dict = _Py_GetGlobalVariablesAsDict();
2546 if (dict == NULL) {
2547 goto error;
2548 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002549 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002550 goto error;
2551 }
2552 Py_CLEAR(dict);
2553
2554 /* pre config */
2555 PyInterpreterState *interp = _PyInterpreterState_Get();
Victor Stinner331a6a52019-05-27 16:39:22 +02002556 const PyPreConfig *pre_config = &_PyRuntime.preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002557 dict = _PyPreConfig_AsDict(pre_config);
2558 if (dict == NULL) {
2559 goto error;
2560 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002561 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002562 goto error;
2563 }
2564 Py_CLEAR(dict);
2565
2566 /* core config */
Victor Stinner331a6a52019-05-27 16:39:22 +02002567 const PyConfig *config = &interp->config;
2568 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002569 if (dict == NULL) {
2570 goto error;
2571 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002572 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002573 goto error;
2574 }
2575 Py_CLEAR(dict);
2576
Victor Stinner331a6a52019-05-27 16:39:22 +02002577 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002578
2579error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002580 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002581 Py_XDECREF(dict);
2582 return NULL;
2583}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002584
2585
2586static void
2587init_dump_ascii_wstr(const wchar_t *str)
2588{
2589 if (str == NULL) {
2590 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002591 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002592 }
2593
2594 PySys_WriteStderr("'");
2595 for (; *str != L'\0'; str++) {
2596 wchar_t ch = *str;
2597 if (ch == L'\'') {
2598 PySys_WriteStderr("\\'");
2599 } else if (0x20 <= ch && ch < 0x7f) {
2600 PySys_WriteStderr("%lc", ch);
2601 }
2602 else if (ch <= 0xff) {
2603 PySys_WriteStderr("\\x%02x", ch);
2604 }
2605#if SIZEOF_WCHAR_T > 2
2606 else if (ch > 0xffff) {
2607 PySys_WriteStderr("\\U%08x", ch);
2608 }
2609#endif
2610 else {
2611 PySys_WriteStderr("\\u%04x", ch);
2612 }
2613 }
2614 PySys_WriteStderr("'");
2615}
2616
2617
2618/* Dump the Python path configuration into sys.stderr */
2619void
2620_Py_DumpPathConfig(PyThreadState *tstate)
2621{
2622 PyObject *exc_type, *exc_value, *exc_tb;
2623 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2624
2625 PySys_WriteStderr("Python path configuration:\n");
2626
2627#define DUMP_CONFIG(NAME, FIELD) \
2628 do { \
2629 PySys_WriteStderr(" " NAME " = "); \
2630 init_dump_ascii_wstr(config->FIELD); \
2631 PySys_WriteStderr("\n"); \
2632 } while (0)
2633
2634 PyConfig *config = &tstate->interp->config;
2635 DUMP_CONFIG("PYTHONHOME", home);
2636 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2637 DUMP_CONFIG("program name", program_name);
2638 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2639 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2640 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2641 PySys_WriteStderr(" import site = %i\n", config->site_import);
2642#undef DUMP_CONFIG
2643
2644#define DUMP_SYS(NAME) \
2645 do { \
2646 obj = PySys_GetObject(#NAME); \
2647 PySys_FormatStderr(" sys.%s = ", #NAME); \
2648 if (obj != NULL) { \
2649 PySys_FormatStderr("%A", obj); \
2650 } \
2651 else { \
2652 PySys_WriteStderr("(not set)"); \
2653 } \
2654 PySys_FormatStderr("\n"); \
2655 } while (0)
2656
2657 PyObject *obj;
2658 DUMP_SYS(_base_executable);
2659 DUMP_SYS(base_prefix);
2660 DUMP_SYS(base_exec_prefix);
2661 DUMP_SYS(executable);
2662 DUMP_SYS(prefix);
2663 DUMP_SYS(exec_prefix);
2664#undef DUMP_SYS
2665
2666 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2667 if (sys_path != NULL && PyList_Check(sys_path)) {
2668 PySys_WriteStderr(" sys.path = [\n");
2669 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2670 for (Py_ssize_t i=0; i < len; i++) {
2671 PyObject *path = PyList_GET_ITEM(sys_path, i);
2672 PySys_FormatStderr(" %A,\n", path);
2673 }
2674 PySys_WriteStderr(" ]\n");
2675 }
2676
2677 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2678}