blob: a0b2691bcd75caca645821e35a255889c48e5162 [file] [log] [blame]
Victor Stinner6c785c02018-08-01 17:56:14 +02001#include "Python.h"
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002#include "osdefs.h" /* DELIM */
Victor Stinner9fc57a32018-11-07 00:44:03 +01003#include "pycore_fileutils.h"
Victor Stinner95e2cbf2019-03-01 16:25:19 +01004#include "pycore_getopt.h"
Victor Stinnerc5c64252019-09-23 15:59:00 +02005#include "pycore_initconfig.h"
6#include "pycore_pathconfig.h"
7#include "pycore_pyerrors.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01008#include "pycore_pylifecycle.h"
9#include "pycore_pymem.h"
Victor Stinner6d5ee972019-03-23 12:05:43 +010010#include "pycore_pystate.h" /* _PyRuntime */
Victor Stinner95e2cbf2019-03-01 16:25:19 +010011#include <locale.h> /* setlocale() */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020012#ifdef HAVE_LANGINFO_H
Victor Stinner95e2cbf2019-03-01 16:25:19 +010013# include <langinfo.h> /* nl_langinfo(CODESET) */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020014#endif
Victor Stinner95e2cbf2019-03-01 16:25:19 +010015#if defined(MS_WINDOWS) || defined(__CYGWIN__)
16# include <windows.h> /* GetACP() */
17# ifdef HAVE_IO_H
18# include <io.h>
19# endif
20# ifdef HAVE_FCNTL_H
21# include <fcntl.h> /* O_BINARY */
22# endif
Victor Stinnerb2457ef2018-08-29 13:25:36 +020023#endif
24
Victor Stinner6c785c02018-08-01 17:56:14 +020025
Victor Stinner95e2cbf2019-03-01 16:25:19 +010026/* --- Command line options --------------------------------------- */
27
Victor Stinner95e2cbf2019-03-01 16:25:19 +010028/* Short usage message (with %s for argv0) */
29static const char usage_line[] =
30"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
31
32/* Long usage message, split into parts < 512 bytes */
33static const char usage_1[] = "\
34Options and arguments (and corresponding environment variables):\n\
35-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
36 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
37-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
38-c cmd : program passed in as string (terminates option list)\n\
39-d : debug output from parser; also PYTHONDEBUG=x\n\
40-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
41-h : print this help message and exit (also --help)\n\
42";
43static const char usage_2[] = "\
44-i : inspect interactively after running script; forces a prompt even\n\
45 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
46-I : isolate Python from the user's environment (implies -E and -s)\n\
47-m mod : run library module as a script (terminates option list)\n\
48-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
49 .pyc extension; also PYTHONOPTIMIZE=x\n\
50-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
51 .pyc extension\n\
52-q : don't print version and copyright messages on interactive startup\n\
53-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
54-S : don't imply 'import site' on initialization\n\
55";
56static const char usage_3[] = "\
57-u : force the stdout and stderr streams to be unbuffered;\n\
58 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
59-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
60 can be supplied multiple times to increase verbosity\n\
61-V : print the Python version number and exit (also --version)\n\
62 when given twice, print more information about the build\n\
63-W arg : warning control; arg is action:message:category:module:lineno\n\
64 also PYTHONWARNINGS=arg\n\
65-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
Pablo Galindo13951c72020-02-23 20:48:27 +000066-X opt : set implementation-specific option. The following options are available:\n\
67\n\
68 -X faulthandler: enable faulthandler\n\
69 -X showrefcount: output the total reference count and number of used\n\
70 memory blocks when the program finishes or after each statement in the\n\
71 interactive interpreter. This only works on debug builds\n\
72 -X tracemalloc: start tracing Python memory allocations using the\n\
73 tracemalloc module. By default, only the most recent frame is stored in a\n\
74 traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\
75 traceback limit of NFRAME frames\n\
76 -X showalloccount: output the total count of allocated objects for each\n\
77 type when the program finishes. This only works when Python was built with\n\
78 COUNT_ALLOCS defined\n\
79 -X importtime: show how long each import takes. It shows module name,\n\
80 cumulative time (including nested imports) and self time (excluding\n\
81 nested imports). Note that its output may be broken in multi-threaded\n\
82 application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
83 -X dev: enable CPythons development mode”, introducing additional runtime\n\
84 checks which are too expensive to be enabled by default. Effect of the\n\
85 developer mode:\n\
86 * Add default warning filter, as -W default\n\
87 * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\
88 * Enable the faulthandler module to dump the Python traceback on a crash\n\
89 * Enable asyncio debug mode\n\
90 * Set the dev_mode attribute of sys.flags to True\n\
91 * io.IOBase destructor logs close() exceptions\n\
92 -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\
93 locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\
94 otherwise activate automatically)\n\
95 -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
96 given directory instead of to the code tree\n\
97\n\
Victor Stinner95e2cbf2019-03-01 16:25:19 +010098--check-hash-based-pycs always|default|never:\n\
99 control how Python invalidates hash-based .pyc files\n\
100";
101static const char usage_4[] = "\
102file : program read from script file\n\
103- : program read from stdin (default; interactive mode if a tty)\n\
104arg ...: arguments passed to program in sys.argv[1:]\n\n\
105Other environment variables:\n\
106PYTHONSTARTUP: file executed on interactive startup (no default)\n\
107PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
108 default module search path. The result is sys.path.\n\
109";
110static const char usage_5[] =
111"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
112" The default module search path uses %s.\n"
113"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
Miss Islington (bot)4a5db782019-12-14 02:38:35 -0800114"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100115"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
116"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
117static const char usage_6[] =
118"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Miss Islington (bot)076d0b92019-08-24 03:19:51 -0700119" to seed the hashes of str and bytes objects. It can also be set to an\n"
120" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100121" predictable seed.\n"
122"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
123" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
124" hooks.\n"
125"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
126" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
127" locale coercion and locale compatibility warnings on stderr.\n"
128"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
129" debugger. It can be set to the callable of your debugger of choice.\n"
130"PYTHONDEVMODE: enable the development mode.\n"
131"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
132
133#if defined(MS_WINDOWS)
134# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
135#else
136# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
137#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200138
139
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100140/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200141
Victor Stinner6c785c02018-08-01 17:56:14 +0200142/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200143 stdin and stdout error handler to "surrogateescape". */
144int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200145int Py_DebugFlag = 0; /* Needed by parser.c */
146int Py_VerboseFlag = 0; /* Needed by import.c */
147int Py_QuietFlag = 0; /* Needed by sysmodule.c */
148int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
149int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
150int Py_OptimizeFlag = 0; /* Needed by compile.c */
151int Py_NoSiteFlag = 0; /* Suppress 'import site' */
152int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
153int Py_FrozenFlag = 0; /* Needed by getpath.c */
154int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
155int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
156int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
157int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
158int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
159int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
160#ifdef MS_WINDOWS
161int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
162int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
163#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200164
165
Victor Stinner1075d162019-03-25 23:19:57 +0100166static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100167_Py_GetGlobalVariablesAsDict(void)
168{
169 PyObject *dict, *obj;
170
171 dict = PyDict_New();
172 if (dict == NULL) {
173 return NULL;
174 }
175
176#define SET_ITEM(KEY, EXPR) \
177 do { \
178 obj = (EXPR); \
179 if (obj == NULL) { \
180 return NULL; \
181 } \
182 int res = PyDict_SetItemString(dict, (KEY), obj); \
183 Py_DECREF(obj); \
184 if (res < 0) { \
185 goto fail; \
186 } \
187 } while (0)
188#define SET_ITEM_INT(VAR) \
189 SET_ITEM(#VAR, PyLong_FromLong(VAR))
190#define FROM_STRING(STR) \
191 ((STR != NULL) ? \
192 PyUnicode_FromString(STR) \
193 : (Py_INCREF(Py_None), Py_None))
194#define SET_ITEM_STR(VAR) \
195 SET_ITEM(#VAR, FROM_STRING(VAR))
196
197 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
198 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
199 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
200 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
201
202 SET_ITEM_INT(Py_UTF8Mode);
203 SET_ITEM_INT(Py_DebugFlag);
204 SET_ITEM_INT(Py_VerboseFlag);
205 SET_ITEM_INT(Py_QuietFlag);
206 SET_ITEM_INT(Py_InteractiveFlag);
207 SET_ITEM_INT(Py_InspectFlag);
208
209 SET_ITEM_INT(Py_OptimizeFlag);
210 SET_ITEM_INT(Py_NoSiteFlag);
211 SET_ITEM_INT(Py_BytesWarningFlag);
212 SET_ITEM_INT(Py_FrozenFlag);
213 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
214 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
215 SET_ITEM_INT(Py_NoUserSiteDirectory);
216 SET_ITEM_INT(Py_UnbufferedStdioFlag);
217 SET_ITEM_INT(Py_HashRandomizationFlag);
218 SET_ITEM_INT(Py_IsolatedFlag);
219
220#ifdef MS_WINDOWS
221 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
222 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
223#endif
224
225 return dict;
226
227fail:
228 Py_DECREF(dict);
229 return NULL;
230
231#undef FROM_STRING
232#undef SET_ITEM
233#undef SET_ITEM_INT
234#undef SET_ITEM_STR
235}
236
237
Victor Stinner331a6a52019-05-27 16:39:22 +0200238/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200239
Victor Stinner331a6a52019-05-27 16:39:22 +0200240PyStatus PyStatus_Ok(void)
241{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200242
Victor Stinner331a6a52019-05-27 16:39:22 +0200243PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200244{
Victor Stinner331a6a52019-05-27 16:39:22 +0200245 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner871ff772019-05-17 23:54:00 +0200246 .err_msg = err_msg};
247}
248
Victor Stinner331a6a52019-05-27 16:39:22 +0200249PyStatus PyStatus_NoMemory(void)
250{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200251
Victor Stinner331a6a52019-05-27 16:39:22 +0200252PyStatus PyStatus_Exit(int exitcode)
253{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200254
255
Victor Stinner331a6a52019-05-27 16:39:22 +0200256int PyStatus_IsError(PyStatus status)
257{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200258
Victor Stinner331a6a52019-05-27 16:39:22 +0200259int PyStatus_IsExit(PyStatus status)
260{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200261
Victor Stinner331a6a52019-05-27 16:39:22 +0200262int PyStatus_Exception(PyStatus status)
263{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200264
265
Victor Stinner331a6a52019-05-27 16:39:22 +0200266/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100267
268#ifndef NDEBUG
269int
Victor Stinner331a6a52019-05-27 16:39:22 +0200270_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100271{
272 assert(list->length >= 0);
273 if (list->length != 0) {
274 assert(list->items != NULL);
275 }
276 for (Py_ssize_t i = 0; i < list->length; i++) {
277 assert(list->items[i] != NULL);
278 }
279 return 1;
280}
281#endif /* Py_DEBUG */
282
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100283
Victor Stinner6c785c02018-08-01 17:56:14 +0200284void
Victor Stinner331a6a52019-05-27 16:39:22 +0200285_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200286{
Victor Stinner331a6a52019-05-27 16:39:22 +0200287 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100288 for (Py_ssize_t i=0; i < list->length; i++) {
289 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200290 }
Victor Stinner74f65682019-03-15 15:08:05 +0100291 PyMem_RawFree(list->items);
292 list->length = 0;
293 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200294}
295
296
Victor Stinner74f65682019-03-15 15:08:05 +0100297int
Victor Stinner331a6a52019-05-27 16:39:22 +0200298_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200299{
Victor Stinner331a6a52019-05-27 16:39:22 +0200300 assert(_PyWideStringList_CheckConsistency(list));
301 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100302
303 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200304 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100305 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300306 }
Victor Stinner74f65682019-03-15 15:08:05 +0100307
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -0700308 PyWideStringList copy = _PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100309
310 size_t size = list2->length * sizeof(list2->items[0]);
311 copy.items = PyMem_RawMalloc(size);
312 if (copy.items == NULL) {
313 return -1;
314 }
315
316 for (Py_ssize_t i=0; i < list2->length; i++) {
317 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
318 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200319 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100320 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200321 }
Victor Stinner74f65682019-03-15 15:08:05 +0100322 copy.items[i] = item;
323 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200324 }
Victor Stinner74f65682019-03-15 15:08:05 +0100325
Victor Stinner331a6a52019-05-27 16:39:22 +0200326 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100327 *list = copy;
328 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200329}
330
331
Victor Stinner331a6a52019-05-27 16:39:22 +0200332PyStatus
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700333PyWideStringList_Insert(PyWideStringList *list,
334 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100335{
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700336 Py_ssize_t len = list->length;
337 if (len == PY_SSIZE_T_MAX) {
Kyle Stanley24b5b362019-07-21 22:48:45 -0400338 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200339 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100340 }
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700341 if (index < 0) {
342 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
343 }
344 if (index > len) {
345 index = len;
346 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100347
Victor Stinner74f65682019-03-15 15:08:05 +0100348 wchar_t *item2 = _PyMem_RawWcsdup(item);
349 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200350 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100351 }
Victor Stinner74f65682019-03-15 15:08:05 +0100352
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700353 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100354 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
355 if (items2 == NULL) {
356 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200357 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100358 }
359
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700360 if (index < len) {
361 memmove(&items2[index + 1],
362 &items2[index],
363 (len - index) * sizeof(items2[0]));
364 }
365
366 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100367 list->items = items2;
368 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200369 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100370}
371
372
Victor Stinner331a6a52019-05-27 16:39:22 +0200373PyStatus
Miss Islington (bot)a6427cb2019-08-23 09:24:42 -0700374PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
375{
376 return PyWideStringList_Insert(list, list->length, item);
377}
378
379
380PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200381_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100382{
383 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200384 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
385 if (_PyStatus_EXCEPTION(status)) {
386 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100387 }
388 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200389 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100390}
391
392
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100393static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200394_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100395{
396 for (Py_ssize_t i = 0; i < list->length; i++) {
397 if (wcscmp(list->items[i], item) == 0) {
398 return 1;
399 }
400 }
401 return 0;
402}
403
404
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100405PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200406_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100407{
Victor Stinner331a6a52019-05-27 16:39:22 +0200408 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100409
Victor Stinner74f65682019-03-15 15:08:05 +0100410 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100411 if (pylist == NULL) {
412 return NULL;
413 }
414
Victor Stinner74f65682019-03-15 15:08:05 +0100415 for (Py_ssize_t i = 0; i < list->length; i++) {
416 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
417 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100418 Py_DECREF(pylist);
419 return NULL;
420 }
Victor Stinner74f65682019-03-15 15:08:05 +0100421 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100422 }
423 return pylist;
424}
425
426
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100427/* --- Py_SetStandardStreamEncoding() ----------------------------- */
428
Victor Stinner124b9eb2018-08-29 01:29:06 +0200429/* Helper to allow an embedding application to override the normal
430 * mechanism that attempts to figure out an appropriate IO encoding
431 */
432
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200433static char *_Py_StandardStreamEncoding = NULL;
434static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200435
436int
437Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
438{
439 if (Py_IsInitialized()) {
440 /* This is too late to have any effect */
441 return -1;
442 }
443
444 int res = 0;
445
446 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
447 but Py_Initialize() can change the allocator. Use a known allocator
448 to be able to release the memory later. */
449 PyMemAllocatorEx old_alloc;
450 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
451
452 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
453 * initialised yet.
454 *
455 * However, the raw memory allocators are initialised appropriately
456 * as C static variables, so _PyMem_RawStrdup is OK even though
457 * Py_Initialize hasn't been called yet.
458 */
459 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200460 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200461 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
462 if (!_Py_StandardStreamEncoding) {
463 res = -2;
464 goto done;
465 }
466 }
467 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200468 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200469 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
470 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200471 PyMem_RawFree(_Py_StandardStreamEncoding);
472 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200473 res = -3;
474 goto done;
475 }
476 }
477#ifdef MS_WINDOWS
478 if (_Py_StandardStreamEncoding) {
479 /* Overriding the stream encoding implies legacy streams */
480 Py_LegacyWindowsStdioFlag = 1;
481 }
482#endif
483
484done:
485 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
486
487 return res;
488}
489
490
491void
492_Py_ClearStandardStreamEncoding(void)
493{
494 /* Use the same allocator than Py_SetStandardStreamEncoding() */
495 PyMemAllocatorEx old_alloc;
496 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
497
498 /* We won't need them anymore. */
499 if (_Py_StandardStreamEncoding) {
500 PyMem_RawFree(_Py_StandardStreamEncoding);
501 _Py_StandardStreamEncoding = NULL;
502 }
503 if (_Py_StandardStreamErrors) {
504 PyMem_RawFree(_Py_StandardStreamErrors);
505 _Py_StandardStreamErrors = NULL;
506 }
507
508 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
509}
510
511
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100512/* --- Py_GetArgcArgv() ------------------------------------------- */
513
514/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200515static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100516
517
518void
519_Py_ClearArgcArgv(void)
520{
521 PyMemAllocatorEx old_alloc;
522 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
523
Victor Stinner331a6a52019-05-27 16:39:22 +0200524 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100525
526 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
527}
528
529
Victor Stinner4fffd382019-03-06 01:44:31 +0100530static int
Victor Stinner74f65682019-03-15 15:08:05 +0100531_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100532{
Victor Stinner331a6a52019-05-27 16:39:22 +0200533 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100534 int res;
535
536 PyMemAllocatorEx old_alloc;
537 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
538
Victor Stinner331a6a52019-05-27 16:39:22 +0200539 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100540
541 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
542 return res;
543}
544
545
546/* Make the *original* argc/argv available to other modules.
547 This is rare, but it is needed by the secureware extension. */
548void
549Py_GetArgcArgv(int *argc, wchar_t ***argv)
550{
Victor Stinner74f65682019-03-15 15:08:05 +0100551 *argc = (int)orig_argv.length;
552 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100553}
554
555
Victor Stinner331a6a52019-05-27 16:39:22 +0200556/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100557
558#define DECODE_LOCALE_ERR(NAME, LEN) \
559 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200560 ? _PyStatus_ERR("cannot decode " NAME) \
561 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100562
Victor Stinner6e128382019-09-28 04:50:43 +0200563
Victor Stinner6c785c02018-08-01 17:56:14 +0200564/* Free memory allocated in config, but don't clear all attributes */
565void
Victor Stinner331a6a52019-05-27 16:39:22 +0200566PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200567{
568#define CLEAR(ATTR) \
569 do { \
570 PyMem_RawFree(ATTR); \
571 ATTR = NULL; \
572 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200573
574 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200575 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200576 CLEAR(config->home);
577 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200578
Victor Stinner331a6a52019-05-27 16:39:22 +0200579 _PyWideStringList_Clear(&config->argv);
580 _PyWideStringList_Clear(&config->warnoptions);
581 _PyWideStringList_Clear(&config->xoptions);
582 _PyWideStringList_Clear(&config->module_search_paths);
583 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200584
585 CLEAR(config->executable);
Steve Dower323e7432019-06-29 14:28:59 -0700586 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200587 CLEAR(config->prefix);
588 CLEAR(config->base_prefix);
589 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200590 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200591
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200592 CLEAR(config->filesystem_encoding);
593 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200594 CLEAR(config->stdio_encoding);
595 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100596 CLEAR(config->run_command);
597 CLEAR(config->run_module);
598 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400599 CLEAR(config->check_hash_pycs_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200600#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200601}
602
603
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700604void
Victor Stinner331a6a52019-05-27 16:39:22 +0200605_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200606{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200607 memset(config, 0, sizeof(*config));
Victor Stinner6e128382019-09-28 04:50:43 +0200608
Victor Stinner022be022019-05-22 23:58:50 +0200609 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200610 config->isolated = -1;
611 config->use_environment = -1;
612 config->dev_mode = -1;
613 config->install_signal_handlers = 1;
614 config->use_hash_seed = -1;
615 config->faulthandler = -1;
616 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200617 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200618 config->parse_argv = 0;
619 config->site_import = -1;
620 config->bytes_warning = -1;
621 config->inspect = -1;
622 config->interactive = -1;
623 config->optimization_level = -1;
624 config->parser_debug= -1;
625 config->write_bytecode = -1;
626 config->verbose = -1;
627 config->quiet = -1;
628 config->user_site_directory = -1;
629 config->configure_c_stdio = 0;
630 config->buffered_stdio = -1;
631 config->_install_importlib = 1;
632 config->check_hash_pycs_mode = NULL;
633 config->pathconfig_warnings = -1;
634 config->_init_main = 1;
635#ifdef MS_WINDOWS
636 config->legacy_windows_stdio = -1;
637#endif
638}
639
640
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700641static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200642config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200643{
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700644 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200645
646 config->isolated = 0;
647 config->use_environment = 1;
648 config->site_import = 1;
649 config->bytes_warning = 0;
650 config->inspect = 0;
651 config->interactive = 0;
652 config->optimization_level = 0;
653 config->parser_debug= 0;
654 config->write_bytecode = 1;
655 config->verbose = 0;
656 config->quiet = 0;
657 config->user_site_directory = 1;
658 config->buffered_stdio = 1;
659 config->pathconfig_warnings = 1;
660#ifdef MS_WINDOWS
661 config->legacy_windows_stdio = 0;
662#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200663}
664
665
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700666void
Victor Stinner331a6a52019-05-27 16:39:22 +0200667PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200668{
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700669 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200670
Victor Stinner022be022019-05-22 23:58:50 +0200671 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200672 config->configure_c_stdio = 1;
673 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200674}
675
676
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700677void
Victor Stinner331a6a52019-05-27 16:39:22 +0200678PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200679{
Miss Islington (bot)d49f0962019-10-01 03:26:04 -0700680 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200681
Victor Stinner022be022019-05-22 23:58:50 +0200682 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200683 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200684 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200685 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200686 config->dev_mode = 0;
687 config->install_signal_handlers = 0;
688 config->use_hash_seed = 0;
689 config->faulthandler = 0;
690 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200691 config->pathconfig_warnings = 0;
692#ifdef MS_WINDOWS
693 config->legacy_windows_stdio = 0;
694#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200695}
696
697
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200698/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200699PyStatus
700PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200701{
Victor Stinner331a6a52019-05-27 16:39:22 +0200702 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
703 if (_PyStatus_EXCEPTION(status)) {
704 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200705 }
706
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200707 wchar_t *str2;
708 if (str != NULL) {
709 str2 = _PyMem_RawWcsdup(str);
710 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200711 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200712 }
713 }
714 else {
715 str2 = NULL;
716 }
717 PyMem_RawFree(*config_str);
718 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200719 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200720}
721
722
Victor Stinner331a6a52019-05-27 16:39:22 +0200723static PyStatus
724config_set_bytes_string(PyConfig *config, wchar_t **config_str,
725 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200726{
Victor Stinner331a6a52019-05-27 16:39:22 +0200727 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
728 if (_PyStatus_EXCEPTION(status)) {
729 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400730 }
731
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200732 wchar_t *str2;
733 if (str != NULL) {
734 size_t len;
735 str2 = Py_DecodeLocale(str, &len);
736 if (str2 == NULL) {
737 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200738 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200739 }
740 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200741 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200742 }
743 }
744 }
745 else {
746 str2 = NULL;
747 }
748 PyMem_RawFree(*config_str);
749 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200750 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200751}
752
753
Victor Stinner331a6a52019-05-27 16:39:22 +0200754#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
755 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400756
757
Victor Stinner70005ac2019-05-02 15:25:34 -0400758/* Decode str using Py_DecodeLocale() and set the result into *config_str.
759 Pre-initialize Python if needed to ensure that encodings are properly
760 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200761PyStatus
762PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200763 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400764{
Victor Stinner331a6a52019-05-27 16:39:22 +0200765 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400766}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200767
768
Victor Stinner331a6a52019-05-27 16:39:22 +0200769PyStatus
770_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200771{
Victor Stinner331a6a52019-05-27 16:39:22 +0200772 PyStatus status;
Victor Stinner6e128382019-09-28 04:50:43 +0200773
Victor Stinner331a6a52019-05-27 16:39:22 +0200774 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200775
776#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200777#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200778 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200779 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
780 if (_PyStatus_EXCEPTION(status)) { \
781 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200782 } \
783 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100784#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200785 do { \
Miss Islington (bot)96f581c2019-07-01 10:39:58 -0700786 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200787 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200788 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200789 } while (0)
790
Victor Stinner6d1c4672019-05-20 11:02:00 +0200791 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100792 COPY_ATTR(isolated);
793 COPY_ATTR(use_environment);
794 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200795 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200796 COPY_ATTR(use_hash_seed);
797 COPY_ATTR(hash_seed);
798 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200799 COPY_ATTR(faulthandler);
800 COPY_ATTR(tracemalloc);
801 COPY_ATTR(import_time);
802 COPY_ATTR(show_ref_count);
803 COPY_ATTR(show_alloc_count);
804 COPY_ATTR(dump_refs);
805 COPY_ATTR(malloc_stats);
806
Victor Stinner124b9eb2018-08-29 01:29:06 +0200807 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200808 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200809 COPY_WSTR_ATTR(home);
810 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200811
Victor Stinnerae239f62019-05-16 17:02:56 +0200812 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100813 COPY_WSTRLIST(argv);
814 COPY_WSTRLIST(warnoptions);
815 COPY_WSTRLIST(xoptions);
816 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200817 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200818
Victor Stinner124b9eb2018-08-29 01:29:06 +0200819 COPY_WSTR_ATTR(executable);
Steve Dower323e7432019-06-29 14:28:59 -0700820 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200821 COPY_WSTR_ATTR(prefix);
822 COPY_WSTR_ATTR(base_prefix);
823 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200824 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200825
Victor Stinner6c785c02018-08-01 17:56:14 +0200826 COPY_ATTR(site_import);
827 COPY_ATTR(bytes_warning);
828 COPY_ATTR(inspect);
829 COPY_ATTR(interactive);
830 COPY_ATTR(optimization_level);
831 COPY_ATTR(parser_debug);
832 COPY_ATTR(write_bytecode);
833 COPY_ATTR(verbose);
834 COPY_ATTR(quiet);
835 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200836 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200837 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400838 COPY_WSTR_ATTR(filesystem_encoding);
839 COPY_WSTR_ATTR(filesystem_errors);
840 COPY_WSTR_ATTR(stdio_encoding);
841 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200842#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200843 COPY_ATTR(legacy_windows_stdio);
844#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100845 COPY_ATTR(skip_source_first_line);
846 COPY_WSTR_ATTR(run_command);
847 COPY_WSTR_ATTR(run_module);
848 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400849 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200850 COPY_ATTR(pathconfig_warnings);
851 COPY_ATTR(_init_main);
Victor Stinner6c785c02018-08-01 17:56:14 +0200852
853#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200854#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200855#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200856 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200857}
858
859
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100860static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200861config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100862{
863 PyObject *dict;
864
865 dict = PyDict_New();
866 if (dict == NULL) {
867 return NULL;
868 }
869
870#define SET_ITEM(KEY, EXPR) \
871 do { \
872 PyObject *obj = (EXPR); \
873 if (obj == NULL) { \
874 goto fail; \
875 } \
876 int res = PyDict_SetItemString(dict, (KEY), obj); \
877 Py_DECREF(obj); \
878 if (res < 0) { \
879 goto fail; \
880 } \
881 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100882#define SET_ITEM_INT(ATTR) \
883 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
884#define SET_ITEM_UINT(ATTR) \
885 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100886#define FROM_WSTRING(STR) \
887 ((STR != NULL) ? \
888 PyUnicode_FromWideChar(STR, -1) \
889 : (Py_INCREF(Py_None), Py_None))
890#define SET_ITEM_WSTR(ATTR) \
891 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
892#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200893 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100894
Victor Stinner6d1c4672019-05-20 11:02:00 +0200895 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100896 SET_ITEM_INT(isolated);
897 SET_ITEM_INT(use_environment);
898 SET_ITEM_INT(dev_mode);
899 SET_ITEM_INT(install_signal_handlers);
900 SET_ITEM_INT(use_hash_seed);
901 SET_ITEM_UINT(hash_seed);
902 SET_ITEM_INT(faulthandler);
903 SET_ITEM_INT(tracemalloc);
904 SET_ITEM_INT(import_time);
905 SET_ITEM_INT(show_ref_count);
906 SET_ITEM_INT(show_alloc_count);
907 SET_ITEM_INT(dump_refs);
908 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400909 SET_ITEM_WSTR(filesystem_encoding);
910 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100911 SET_ITEM_WSTR(pycache_prefix);
912 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200913 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100914 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100915 SET_ITEM_WSTRLIST(xoptions);
916 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200917 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100918 SET_ITEM_WSTR(home);
919 SET_ITEM_WSTRLIST(module_search_paths);
920 SET_ITEM_WSTR(executable);
Steve Dower323e7432019-06-29 14:28:59 -0700921 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100922 SET_ITEM_WSTR(prefix);
923 SET_ITEM_WSTR(base_prefix);
924 SET_ITEM_WSTR(exec_prefix);
925 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100926 SET_ITEM_INT(site_import);
927 SET_ITEM_INT(bytes_warning);
928 SET_ITEM_INT(inspect);
929 SET_ITEM_INT(interactive);
930 SET_ITEM_INT(optimization_level);
931 SET_ITEM_INT(parser_debug);
932 SET_ITEM_INT(write_bytecode);
933 SET_ITEM_INT(verbose);
934 SET_ITEM_INT(quiet);
935 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200936 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100937 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400938 SET_ITEM_WSTR(stdio_encoding);
939 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100940#ifdef MS_WINDOWS
941 SET_ITEM_INT(legacy_windows_stdio);
942#endif
943 SET_ITEM_INT(skip_source_first_line);
944 SET_ITEM_WSTR(run_command);
945 SET_ITEM_WSTR(run_module);
946 SET_ITEM_WSTR(run_filename);
947 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400948 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200949 SET_ITEM_INT(pathconfig_warnings);
950 SET_ITEM_INT(_init_main);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100951
952 return dict;
953
954fail:
955 Py_DECREF(dict);
956 return NULL;
957
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100958#undef FROM_WSTRING
959#undef SET_ITEM
960#undef SET_ITEM_INT
961#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100962#undef SET_ITEM_WSTR
963#undef SET_ITEM_WSTRLIST
964}
965
966
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100967static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200968config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200969{
Victor Stinner20004952019-03-26 02:31:11 +0100970 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200971}
972
973
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100974/* Get a copy of the environment variable as wchar_t*.
975 Return 0 on success, but *dest can be NULL.
976 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200977static PyStatus
978config_get_env_dup(PyConfig *config,
979 wchar_t **dest,
980 wchar_t *wname, char *name,
981 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200982{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200983 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100984 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200985
Victor Stinner20004952019-03-26 02:31:11 +0100986 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200987 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200988 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200989 }
990
991#ifdef MS_WINDOWS
992 const wchar_t *var = _wgetenv(wname);
993 if (!var || var[0] == '\0') {
994 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200995 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200996 }
997
Victor Stinner331a6a52019-05-27 16:39:22 +0200998 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +0200999#else
1000 const char *var = getenv(name);
1001 if (!var || var[0] == '\0') {
1002 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001003 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001004 }
1005
Victor Stinner331a6a52019-05-27 16:39:22 +02001006 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001007#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001008}
1009
1010
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001011#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001012 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001013
1014
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001015static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001016config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001017{
Victor Stinner022be022019-05-22 23:58:50 +02001018 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1019 /* Python and Isolated configuration ignore global variables */
1020 return;
1021 }
1022
Victor Stinner6c785c02018-08-01 17:56:14 +02001023#define COPY_FLAG(ATTR, VALUE) \
1024 if (config->ATTR == -1) { \
1025 config->ATTR = VALUE; \
1026 }
1027#define COPY_NOT_FLAG(ATTR, VALUE) \
1028 if (config->ATTR == -1) { \
1029 config->ATTR = !(VALUE); \
1030 }
1031
Victor Stinner20004952019-03-26 02:31:11 +01001032 COPY_FLAG(isolated, Py_IsolatedFlag);
1033 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001034 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1035 COPY_FLAG(inspect, Py_InspectFlag);
1036 COPY_FLAG(interactive, Py_InteractiveFlag);
1037 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1038 COPY_FLAG(parser_debug, Py_DebugFlag);
1039 COPY_FLAG(verbose, Py_VerboseFlag);
1040 COPY_FLAG(quiet, Py_QuietFlag);
1041#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001042 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1043#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001044 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001045
Victor Stinner6c785c02018-08-01 17:56:14 +02001046 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1047 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1048 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1049 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1050
Victor Stinner6c785c02018-08-01 17:56:14 +02001051#undef COPY_FLAG
1052#undef COPY_NOT_FLAG
1053}
1054
1055
1056/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001057static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001058config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001059{
1060#define COPY_FLAG(ATTR, VAR) \
1061 if (config->ATTR != -1) { \
1062 VAR = config->ATTR; \
1063 }
1064#define COPY_NOT_FLAG(ATTR, VAR) \
1065 if (config->ATTR != -1) { \
1066 VAR = !config->ATTR; \
1067 }
1068
Victor Stinner20004952019-03-26 02:31:11 +01001069 COPY_FLAG(isolated, Py_IsolatedFlag);
1070 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001071 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1072 COPY_FLAG(inspect, Py_InspectFlag);
1073 COPY_FLAG(interactive, Py_InteractiveFlag);
1074 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1075 COPY_FLAG(parser_debug, Py_DebugFlag);
1076 COPY_FLAG(verbose, Py_VerboseFlag);
1077 COPY_FLAG(quiet, Py_QuietFlag);
1078#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001079 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1080#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001081 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001082
Victor Stinner6c785c02018-08-01 17:56:14 +02001083 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1084 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1085 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1086 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1087
Victor Stinner6c785c02018-08-01 17:56:14 +02001088 /* Random or non-zero hash seed */
1089 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1090 config->hash_seed != 0);
1091
1092#undef COPY_FLAG
1093#undef COPY_NOT_FLAG
1094}
1095
1096
1097/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1098 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001099static PyStatus
1100config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001101{
Victor Stinner331a6a52019-05-27 16:39:22 +02001102 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001103
Victor Stinner6c785c02018-08-01 17:56:14 +02001104 /* If Py_SetProgramName() was called, use its value */
1105 const wchar_t *program_name = _Py_path_config.program_name;
1106 if (program_name != NULL) {
1107 config->program_name = _PyMem_RawWcsdup(program_name);
1108 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001109 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001110 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001111 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001112 }
1113
1114#ifdef __APPLE__
1115 /* On MacOS X, when the Python interpreter is embedded in an
1116 application bundle, it gets executed by a bootstrapping script
1117 that does os.execve() with an argv[0] that's different from the
1118 actual Python executable. This is needed to keep the Finder happy,
1119 or rather, to work around Apple's overly strict requirements of
1120 the process name. However, we still need a usable sys.executable,
1121 so the actual executable path is passed in an environment variable.
1122 See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
1123 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001124 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001125 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001126 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1127 "PYTHONEXECUTABLE environment variable");
1128 if (_PyStatus_EXCEPTION(status)) {
1129 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001130 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001131 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001132 }
1133#ifdef WITH_NEXT_FRAMEWORK
1134 else {
1135 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1136 if (pyvenv_launcher && *pyvenv_launcher) {
1137 /* Used by Mac/Tools/pythonw.c to forward
1138 * the argv0 of the stub executable
1139 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001140 status = CONFIG_SET_BYTES_STR(config,
1141 &config->program_name,
1142 pyvenv_launcher,
1143 "__PYVENV_LAUNCHER__ environment variable");
1144 if (_PyStatus_EXCEPTION(status)) {
1145 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001146 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001147 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001148 }
1149 }
1150#endif /* WITH_NEXT_FRAMEWORK */
1151#endif /* __APPLE__ */
1152
Victor Stinnerfed02e12019-05-17 11:12:09 +02001153 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001154 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001155 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1156 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1157 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001158 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001159 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001160 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001161 }
1162
Victor Stinnerfed02e12019-05-17 11:12:09 +02001163 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001164#ifdef MS_WINDOWS
1165 const wchar_t *default_program_name = L"python";
1166#else
1167 const wchar_t *default_program_name = L"python3";
1168#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001169 status = PyConfig_SetString(config, &config->program_name,
1170 default_program_name);
1171 if (_PyStatus_EXCEPTION(status)) {
1172 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001173 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001174 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001175}
1176
Victor Stinner331a6a52019-05-27 16:39:22 +02001177static PyStatus
1178config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001179{
1180 assert(config->executable == NULL);
1181
1182 /* If Py_SetProgramFullPath() was called, use its value */
1183 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1184 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001185 PyStatus status = PyConfig_SetString(config,
1186 &config->executable,
1187 program_full_path);
1188 if (_PyStatus_EXCEPTION(status)) {
1189 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001190 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001191 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001192 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001193 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001194}
Victor Stinner6c785c02018-08-01 17:56:14 +02001195
Victor Stinner4fffd382019-03-06 01:44:31 +01001196
Victor Stinner6c785c02018-08-01 17:56:14 +02001197static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001198config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001199{
Victor Stinner74f65682019-03-15 15:08:05 +01001200 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001201}
1202
1203
Victor Stinner331a6a52019-05-27 16:39:22 +02001204static PyStatus
1205config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001206{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001207 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001208
1209 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001210 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001211 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001212 PyStatus status = PyConfig_SetString(config, &config->home, home);
1213 if (_PyStatus_EXCEPTION(status)) {
1214 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001215 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001216 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001217 }
1218
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001219 return CONFIG_GET_ENV_DUP(config, &config->home,
1220 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001221}
1222
1223
Victor Stinner331a6a52019-05-27 16:39:22 +02001224static PyStatus
1225config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001226{
Victor Stinner331a6a52019-05-27 16:39:22 +02001227 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001228
1229 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1230 /* Convert a text seed to a numeric one */
1231 if (seed_text && strcmp(seed_text, "random") != 0) {
1232 const char *endptr = seed_text;
1233 unsigned long seed;
1234 errno = 0;
1235 seed = strtoul(seed_text, (char **)&endptr, 10);
1236 if (*endptr != '\0'
1237 || seed > 4294967295UL
1238 || (errno == ERANGE && seed == ULONG_MAX))
1239 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001240 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001241 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001242 }
1243 /* Use a specific hash */
1244 config->use_hash_seed = 1;
1245 config->hash_seed = seed;
1246 }
1247 else {
1248 /* Use a random hash */
1249 config->use_hash_seed = 0;
1250 config->hash_seed = 0;
1251 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001252 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001253}
1254
1255
Victor Stinner6c785c02018-08-01 17:56:14 +02001256static int
1257config_wstr_to_int(const wchar_t *wstr, int *result)
1258{
1259 const wchar_t *endptr = wstr;
1260 errno = 0;
1261 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1262 if (*endptr != '\0' || errno == ERANGE) {
1263 return -1;
1264 }
1265 if (value < INT_MIN || value > INT_MAX) {
1266 return -1;
1267 }
1268
1269 *result = (int)value;
1270 return 0;
1271}
1272
1273
Victor Stinner331a6a52019-05-27 16:39:22 +02001274static PyStatus
1275config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001276{
Victor Stinner331a6a52019-05-27 16:39:22 +02001277 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001278 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001279
Victor Stinner6c785c02018-08-01 17:56:14 +02001280 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001281 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1282 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1283 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1284 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001285
1286 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001287 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001288 if (dont_write_bytecode) {
1289 config->write_bytecode = 0;
1290 }
1291
1292 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001293 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001294 if (no_user_site_directory) {
1295 config->user_site_directory = 0;
1296 }
1297
1298 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001299 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001300 if (unbuffered_stdio) {
1301 config->buffered_stdio = 0;
1302 }
1303
1304#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001305 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001306 "PYTHONLEGACYWINDOWSSTDIO");
1307#endif
1308
Victor Stinner331a6a52019-05-27 16:39:22 +02001309 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001310 config->dump_refs = 1;
1311 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001312 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001313 config->malloc_stats = 1;
1314 }
1315
Victor Stinner331a6a52019-05-27 16:39:22 +02001316 if (config->pythonpath_env == NULL) {
1317 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1318 L"PYTHONPATH", "PYTHONPATH");
1319 if (_PyStatus_EXCEPTION(status)) {
1320 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001321 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001322 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001323
1324 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001325 status = config_init_hash_seed(config);
1326 if (_PyStatus_EXCEPTION(status)) {
1327 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001328 }
1329 }
1330
Victor Stinner331a6a52019-05-27 16:39:22 +02001331 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001332}
1333
1334
Victor Stinner331a6a52019-05-27 16:39:22 +02001335static PyStatus
1336config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001337{
1338 int nframe;
1339 int valid;
1340
Victor Stinner331a6a52019-05-27 16:39:22 +02001341 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001342 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001343 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001344 valid = (nframe >= 0);
1345 }
1346 else {
1347 valid = 0;
1348 }
1349 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001350 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001351 }
1352 config->tracemalloc = nframe;
1353 }
1354
1355 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1356 if (xoption) {
1357 const wchar_t *sep = wcschr(xoption, L'=');
1358 if (sep) {
1359 if (!config_wstr_to_int(sep + 1, &nframe)) {
1360 valid = (nframe >= 0);
1361 }
1362 else {
1363 valid = 0;
1364 }
1365 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001366 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1367 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001368 }
1369 }
1370 else {
1371 /* -X tracemalloc behaves as -X tracemalloc=1 */
1372 nframe = 1;
1373 }
1374 config->tracemalloc = nframe;
1375 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001376 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001377}
1378
1379
Victor Stinner331a6a52019-05-27 16:39:22 +02001380static PyStatus
1381config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001382{
1383 assert(config->pycache_prefix == NULL);
1384
1385 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1386 if (xoption) {
1387 const wchar_t *sep = wcschr(xoption, L'=');
1388 if (sep && wcslen(sep) > 1) {
1389 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1390 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001391 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001392 }
1393 }
1394 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001395 // PYTHONPYCACHEPREFIX env var ignored
1396 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001397 config->pycache_prefix = NULL;
1398 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001399 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001400 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001401
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001402 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1403 L"PYTHONPYCACHEPREFIX",
1404 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001405}
1406
1407
Victor Stinner331a6a52019-05-27 16:39:22 +02001408static PyStatus
1409config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001410{
1411 /* More complex options configured by env var and -X option */
1412 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001413 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001414 || config_get_xoption(config, L"faulthandler")) {
1415 config->faulthandler = 1;
1416 }
1417 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001418 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001419 || config_get_xoption(config, L"importtime")) {
1420 config->import_time = 1;
1421 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001422
Victor Stinner331a6a52019-05-27 16:39:22 +02001423 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001424 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001425 status = config_init_tracemalloc(config);
1426 if (_PyStatus_EXCEPTION(status)) {
1427 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001428 }
1429 }
1430
1431 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001432 status = config_init_pycache_prefix(config);
1433 if (_PyStatus_EXCEPTION(status)) {
1434 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001435 }
1436 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001437 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001438}
1439
1440
Victor Stinner709d23d2019-05-02 14:56:30 -04001441static const wchar_t *
Victor Stinner331a6a52019-05-27 16:39:22 +02001442config_get_stdio_errors(const PyConfig *config)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001443{
1444#ifndef MS_WINDOWS
1445 const char *loc = setlocale(LC_CTYPE, NULL);
1446 if (loc != NULL) {
1447 /* surrogateescape is the default in the legacy C and POSIX locales */
1448 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001449 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001450 }
1451
1452#ifdef PY_COERCE_C_LOCALE
1453 /* surrogateescape is the default in locale coercion target locales */
1454 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001455 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001456 }
1457#endif
1458 }
1459
Victor Stinner709d23d2019-05-02 14:56:30 -04001460 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001461#else
1462 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001463 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001464#endif
1465}
1466
1467
Victor Stinner331a6a52019-05-27 16:39:22 +02001468static PyStatus
1469config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001470{
1471#ifdef MS_WINDOWS
1472 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001473 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001474 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001475#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001476 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001477#else
1478 const char *encoding = nl_langinfo(CODESET);
1479 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001480 return _PyStatus_ERR("failed to get the locale encoding: "
1481 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001482 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001483 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001484 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001485 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001486 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001487#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001488}
1489
1490
Victor Stinner331a6a52019-05-27 16:39:22 +02001491static PyStatus
1492config_init_stdio_encoding(PyConfig *config,
1493 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001494{
Victor Stinner331a6a52019-05-27 16:39:22 +02001495 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001496
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001497 /* If Py_SetStandardStreamEncoding() have been called, use these
1498 parameters. */
1499 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001500 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1501 _Py_StandardStreamEncoding,
1502 "_Py_StandardStreamEncoding");
1503 if (_PyStatus_EXCEPTION(status)) {
1504 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001505 }
1506 }
1507
1508 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001509 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1510 _Py_StandardStreamErrors,
1511 "_Py_StandardStreamErrors");
1512 if (_PyStatus_EXCEPTION(status)) {
1513 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001514 }
1515 }
1516
1517 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001518 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001519 }
1520
1521 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001522 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001523 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001524 char *pythonioencoding = _PyMem_RawStrdup(opt);
1525 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001526 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001527 }
1528
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001529 char *errors = strchr(pythonioencoding, ':');
1530 if (errors) {
1531 *errors = '\0';
1532 errors++;
1533 if (!errors[0]) {
1534 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001535 }
1536 }
1537
1538 /* Does PYTHONIOENCODING contain an encoding? */
1539 if (pythonioencoding[0]) {
1540 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001541 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1542 pythonioencoding,
1543 "PYTHONIOENCODING environment variable");
1544 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001545 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001546 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001547 }
1548 }
1549
1550 /* If the encoding is set but not the error handler,
1551 use "strict" error handler by default.
1552 PYTHONIOENCODING=latin1 behaves as
1553 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001554 if (!errors) {
1555 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001556 }
1557 }
1558
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001559 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001560 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1561 errors,
1562 "PYTHONIOENCODING environment variable");
1563 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001564 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001565 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001566 }
1567 }
1568
1569 PyMem_RawFree(pythonioencoding);
1570 }
1571
1572 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001573 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001574 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001575 status = PyConfig_SetString(config, &config->stdio_encoding,
1576 L"utf-8");
1577 if (_PyStatus_EXCEPTION(status)) {
1578 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001579 }
1580 }
1581 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001582 status = PyConfig_SetString(config, &config->stdio_errors,
1583 L"surrogateescape");
1584 if (_PyStatus_EXCEPTION(status)) {
1585 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001586 }
1587 }
1588 }
1589
1590 /* Choose the default error handler based on the current locale. */
1591 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001592 status = config_get_locale_encoding(config, &config->stdio_encoding);
1593 if (_PyStatus_EXCEPTION(status)) {
1594 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001595 }
1596 }
1597 if (config->stdio_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001598 const wchar_t *errors = config_get_stdio_errors(config);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001599 assert(errors != NULL);
1600
Victor Stinner331a6a52019-05-27 16:39:22 +02001601 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1602 if (_PyStatus_EXCEPTION(status)) {
1603 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001604 }
1605 }
1606
Victor Stinner331a6a52019-05-27 16:39:22 +02001607 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001608}
1609
1610
Victor Stinner331a6a52019-05-27 16:39:22 +02001611static PyStatus
1612config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001613{
Victor Stinner331a6a52019-05-27 16:39:22 +02001614 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001615
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001616 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001617#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001618 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001619#else
Victor Stinnere2510952019-05-02 11:28:57 -04001620
1621#ifdef MS_WINDOWS
1622 if (preconfig->legacy_windows_fs_encoding) {
1623 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001624 status = PyConfig_SetString(config, &config->filesystem_encoding,
1625 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001626 }
1627 else
1628#endif
Victor Stinner20004952019-03-26 02:31:11 +01001629 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001630 status = PyConfig_SetString(config, &config->filesystem_encoding,
1631 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001632 }
Victor Stinnere2510952019-05-02 11:28:57 -04001633#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001634 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001635 status = PyConfig_SetString(config, &config->filesystem_encoding,
1636 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001637 }
Victor Stinnere2510952019-05-02 11:28:57 -04001638#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001639 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001640#ifdef MS_WINDOWS
1641 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001642 status = PyConfig_SetString(config, &config->filesystem_encoding,
1643 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001644#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001645 status = config_get_locale_encoding(config,
1646 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001647#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001648 }
Victor Stinnere2510952019-05-02 11:28:57 -04001649#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001650
Victor Stinner331a6a52019-05-27 16:39:22 +02001651 if (_PyStatus_EXCEPTION(status)) {
1652 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001653 }
1654 }
1655
1656 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001657 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001658#ifdef MS_WINDOWS
1659 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001660 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001661 }
1662 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001663 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001664 }
1665#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001666 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001667#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001668 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1669 if (_PyStatus_EXCEPTION(status)) {
1670 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001671 }
1672 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001673 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001674}
1675
1676
Victor Stinner331a6a52019-05-27 16:39:22 +02001677static PyStatus
1678config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001679{
Victor Stinner331a6a52019-05-27 16:39:22 +02001680 PyStatus status;
1681 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001682
Victor Stinner20004952019-03-26 02:31:11 +01001683 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001684 status = config_read_env_vars(config);
1685 if (_PyStatus_EXCEPTION(status)) {
1686 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001687 }
1688 }
1689
1690 /* -X options */
1691 if (config_get_xoption(config, L"showrefcount")) {
1692 config->show_ref_count = 1;
1693 }
1694 if (config_get_xoption(config, L"showalloccount")) {
1695 config->show_alloc_count = 1;
1696 }
1697
Victor Stinner331a6a52019-05-27 16:39:22 +02001698 status = config_read_complex_options(config);
1699 if (_PyStatus_EXCEPTION(status)) {
1700 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001701 }
1702
Victor Stinner6c785c02018-08-01 17:56:14 +02001703 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001704 status = config_init_home(config);
1705 if (_PyStatus_EXCEPTION(status)) {
1706 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001707 }
1708 }
1709
Steve Dower177a41a2018-11-17 20:41:48 -08001710 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001711 status = config_init_executable(config);
1712 if (_PyStatus_EXCEPTION(status)) {
1713 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001714 }
1715 }
1716
Victor Stinner6c785c02018-08-01 17:56:14 +02001717 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001718 status = _PyConfig_InitPathConfig(config);
1719 if (_PyStatus_EXCEPTION(status)) {
1720 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001721 }
1722 }
1723
1724 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001725 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001726 if (config->faulthandler < 0) {
1727 config->faulthandler = 1;
1728 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001729 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001730 if (config->faulthandler < 0) {
1731 config->faulthandler = 0;
1732 }
1733 if (config->tracemalloc < 0) {
1734 config->tracemalloc = 0;
1735 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001736 if (config->use_hash_seed < 0) {
1737 config->use_hash_seed = 0;
1738 config->hash_seed = 0;
1739 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001740
Victor Stinner70fead22018-08-29 13:45:34 +02001741 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001742 status = config_init_fs_encoding(config, preconfig);
1743 if (_PyStatus_EXCEPTION(status)) {
1744 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001745 }
1746 }
1747
Victor Stinner331a6a52019-05-27 16:39:22 +02001748 status = config_init_stdio_encoding(config, preconfig);
1749 if (_PyStatus_EXCEPTION(status)) {
1750 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001751 }
1752
Victor Stinner62599762019-03-15 16:03:23 +01001753 if (config->argv.length < 1) {
1754 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001755 status = PyWideStringList_Append(&config->argv, L"");
1756 if (_PyStatus_EXCEPTION(status)) {
1757 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001758 }
1759 }
Victor Stinner870b0352019-05-17 03:15:12 +02001760
1761 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001762 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1763 L"default");
1764 if (_PyStatus_EXCEPTION(status)) {
1765 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001766 }
1767 }
1768
1769 if (config->configure_c_stdio < 0) {
1770 config->configure_c_stdio = 1;
1771 }
1772
Victor Stinner331a6a52019-05-27 16:39:22 +02001773 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001774}
Victor Stinner5ed69952018-11-06 15:59:52 +01001775
1776
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001777static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001778config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001779{
1780#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1781 /* don't translate newlines (\r\n <=> \n) */
1782 _setmode(fileno(stdin), O_BINARY);
1783 _setmode(fileno(stdout), O_BINARY);
1784 _setmode(fileno(stderr), O_BINARY);
1785#endif
1786
1787 if (!config->buffered_stdio) {
1788#ifdef HAVE_SETVBUF
1789 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1790 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1791 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1792#else /* !HAVE_SETVBUF */
1793 setbuf(stdin, (char *)NULL);
1794 setbuf(stdout, (char *)NULL);
1795 setbuf(stderr, (char *)NULL);
1796#endif /* !HAVE_SETVBUF */
1797 }
1798 else if (config->interactive) {
1799#ifdef MS_WINDOWS
1800 /* Doesn't have to have line-buffered -- use unbuffered */
1801 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1802 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1803#else /* !MS_WINDOWS */
1804#ifdef HAVE_SETVBUF
1805 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1806 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1807#endif /* HAVE_SETVBUF */
1808#endif /* !MS_WINDOWS */
1809 /* Leave stderr alone - it should be unbuffered anyway. */
1810 }
1811}
1812
1813
1814/* Write the configuration:
1815
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001816 - set Py_xxx global configuration variables
1817 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001818void
Victor Stinner331a6a52019-05-27 16:39:22 +02001819_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001820{
Victor Stinner331a6a52019-05-27 16:39:22 +02001821 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001822
1823 if (config->configure_c_stdio) {
1824 config_init_stdio(config);
1825 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001826
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001827 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001828 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001829 preconfig->isolated = config->isolated;
1830 preconfig->use_environment = config->use_environment;
1831 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001832}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001833
1834
Victor Stinner331a6a52019-05-27 16:39:22 +02001835/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001836
1837static void
Victor Stinner2f549082019-03-29 15:13:46 +01001838config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001839{
Victor Stinner2f549082019-03-29 15:13:46 +01001840 FILE *f = error ? stderr : stdout;
1841
1842 fprintf(f, usage_line, program);
1843 if (error)
1844 fprintf(f, "Try `python -h' for more information.\n");
1845 else {
1846 fputs(usage_1, f);
1847 fputs(usage_2, f);
1848 fputs(usage_3, f);
1849 fprintf(f, usage_4, (wint_t)DELIM);
1850 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1851 fputs(usage_6, f);
1852 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001853}
1854
1855
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001856/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001857static PyStatus
1858config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001859 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001860{
Victor Stinner331a6a52019-05-27 16:39:22 +02001861 PyStatus status;
1862 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001863 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001864 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001865
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001866 _PyOS_ResetGetOpt();
1867 do {
1868 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001869 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001870 if (c == EOF) {
1871 break;
1872 }
1873
1874 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001875 if (config->run_command == NULL) {
1876 /* -c is the last option; following arguments
1877 that look like options are left for the
1878 command to interpret. */
1879 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1880 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1881 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001882 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001883 }
1884 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1885 command[len - 2] = '\n';
1886 command[len - 1] = 0;
1887 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001888 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001889 break;
1890 }
1891
1892 if (c == 'm') {
1893 /* -m is the last option; following arguments
1894 that look like options are left for the
1895 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001896 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001897 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1898 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001899 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001900 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001901 }
1902 break;
1903 }
1904
1905 switch (c) {
1906 case 0:
1907 // Handle long option.
1908 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001909 if (wcscmp(_PyOS_optarg, L"always") == 0
1910 || wcscmp(_PyOS_optarg, L"never") == 0
1911 || wcscmp(_PyOS_optarg, L"default") == 0)
1912 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001913 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1914 _PyOS_optarg);
1915 if (_PyStatus_EXCEPTION(status)) {
1916 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001917 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001918 } else {
1919 fprintf(stderr, "--check-hash-based-pycs must be one of "
1920 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001921 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001922 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001923 }
1924 break;
1925
1926 case 'b':
1927 config->bytes_warning++;
1928 break;
1929
1930 case 'd':
1931 config->parser_debug++;
1932 break;
1933
1934 case 'i':
1935 config->inspect++;
1936 config->interactive++;
1937 break;
1938
Victor Stinner6dcb5422019-03-05 02:44:12 +01001939 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001940 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001941 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001942 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001943 break;
1944
1945 /* case 'J': reserved for Jython */
1946
1947 case 'O':
1948 config->optimization_level++;
1949 break;
1950
1951 case 'B':
1952 config->write_bytecode = 0;
1953 break;
1954
1955 case 's':
1956 config->user_site_directory = 0;
1957 break;
1958
1959 case 'S':
1960 config->site_import = 0;
1961 break;
1962
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001963 case 't':
1964 /* ignored for backwards compatibility */
1965 break;
1966
1967 case 'u':
1968 config->buffered_stdio = 0;
1969 break;
1970
1971 case 'v':
1972 config->verbose++;
1973 break;
1974
1975 case 'x':
1976 config->skip_source_first_line = 1;
1977 break;
1978
1979 case 'h':
1980 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001981 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001982 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001983
1984 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01001985 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001986 break;
1987
1988 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02001989 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
1990 if (_PyStatus_EXCEPTION(status)) {
1991 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001992 }
1993 break;
1994
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001995 case 'q':
1996 config->quiet++;
1997 break;
1998
1999 case 'R':
2000 config->use_hash_seed = 0;
2001 break;
2002
2003 /* This space reserved for other options */
2004
2005 default:
2006 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002007 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002008 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002009 }
2010 } while (1);
2011
Victor Stinner2f549082019-03-29 15:13:46 +01002012 if (print_version) {
2013 printf("Python %s\n",
2014 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002015 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002016 }
2017
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002018 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002019 && _PyOS_optind < argv->length
2020 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002021 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002022 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002023 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002024 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002025 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002026 }
2027 }
2028
2029 if (config->run_command != NULL || config->run_module != NULL) {
2030 /* Backup _PyOS_optind */
2031 _PyOS_optind--;
2032 }
2033
Victor Stinnerae239f62019-05-16 17:02:56 +02002034 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002035
Victor Stinner331a6a52019-05-27 16:39:22 +02002036 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002037}
2038
2039
2040#ifdef MS_WINDOWS
2041# define WCSTOK wcstok_s
2042#else
2043# define WCSTOK wcstok
2044#endif
2045
2046/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002047static PyStatus
2048config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002049{
Victor Stinner331a6a52019-05-27 16:39:22 +02002050 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002051 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2052 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002053 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002054 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002055 if (_PyStatus_EXCEPTION(status)) {
2056 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002057 }
2058
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002059 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002060 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002061 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002062 }
2063
2064
2065 wchar_t *warning, *context = NULL;
2066 for (warning = WCSTOK(env, L",", &context);
2067 warning != NULL;
2068 warning = WCSTOK(NULL, L",", &context))
2069 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002070 status = PyWideStringList_Append(warnoptions, warning);
2071 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002072 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002073 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002074 }
2075 }
2076 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002077 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002078}
2079
2080
Victor Stinner331a6a52019-05-27 16:39:22 +02002081static PyStatus
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002082warnoptions_append(PyConfig *config, PyWideStringList *options,
2083 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002084{
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002085 /* config_init_warnoptions() add existing config warnoptions at the end:
2086 ensure that the new option is not already present in this list to
2087 prevent change the options order whne config_init_warnoptions() is
2088 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002089 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002090 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002091 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002092 }
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002093 if (_PyWideStringList_Find(options, option)) {
2094 /* Already present: do nothing */
2095 return _PyStatus_OK();
2096 }
2097 return PyWideStringList_Append(options, option);
2098}
2099
2100
2101static PyStatus
2102warnoptions_extend(PyConfig *config, PyWideStringList *options,
2103 const PyWideStringList *options2)
2104{
2105 const Py_ssize_t len = options2->length;
2106 wchar_t *const *items = options2->items;
2107
2108 for (Py_ssize_t i = 0; i < len; i++) {
2109 PyStatus status = warnoptions_append(config, options, items[i]);
2110 if (_PyStatus_EXCEPTION(status)) {
2111 return status;
2112 }
2113 }
2114 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002115}
2116
2117
Victor Stinner331a6a52019-05-27 16:39:22 +02002118static PyStatus
2119config_init_warnoptions(PyConfig *config,
2120 const PyWideStringList *cmdline_warnoptions,
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002121 const PyWideStringList *env_warnoptions,
2122 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002123{
Victor Stinner331a6a52019-05-27 16:39:22 +02002124 PyStatus status;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002125 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002126
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002127 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002128 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002129 * - any implicit filters added by _warnings.c/warnings.py
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002130 * - PyConfig.dev_mode: "default" filter
2131 * - PYTHONWARNINGS environment variable
2132 * - '-W' command line options
2133 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2134 * "default::BytesWarning" or "error::BytesWarning" filter
2135 * - early PySys_AddWarnOption() calls
2136 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002137 *
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002138 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2139 * module works on the basis of "the most recently added filter will be
2140 * checked first", we add the lowest precedence entries first so that later
2141 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002142 */
2143
Victor Stinner20004952019-03-26 02:31:11 +01002144 if (config->dev_mode) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002145 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002146 if (_PyStatus_EXCEPTION(status)) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002147 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002148 }
2149 }
2150
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002151 status = warnoptions_extend(config, &options, env_warnoptions);
2152 if (_PyStatus_EXCEPTION(status)) {
2153 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002154 }
2155
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002156 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2157 if (_PyStatus_EXCEPTION(status)) {
2158 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002159 }
2160
2161 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2162 * don't even try to emit a warning, so we skip setting the filter in that
2163 * case.
2164 */
2165 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002166 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002167 if (config->bytes_warning> 1) {
2168 filter = L"error::BytesWarning";
2169 }
2170 else {
2171 filter = L"default::BytesWarning";
2172 }
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002173 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002174 if (_PyStatus_EXCEPTION(status)) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002175 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002176 }
2177 }
Victor Stinneraf84a882019-08-23 21:16:51 +02002178
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002179 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinneraf84a882019-08-23 21:16:51 +02002180 if (_PyStatus_EXCEPTION(status)) {
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002181 goto error;
Victor Stinneraf84a882019-08-23 21:16:51 +02002182 }
2183
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002184 /* Always add all PyConfig.warnoptions options */
2185 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2186 if (_PyStatus_EXCEPTION(status)) {
2187 goto error;
2188 }
2189
2190 _PyWideStringList_Clear(&config->warnoptions);
2191 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002192 return _PyStatus_OK();
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002193
2194error:
2195 _PyWideStringList_Clear(&options);
2196 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002197}
2198
2199
Victor Stinner331a6a52019-05-27 16:39:22 +02002200static PyStatus
2201config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002202{
Victor Stinner331a6a52019-05-27 16:39:22 +02002203 const PyWideStringList *cmdline_argv = &config->argv;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002204 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002205
Victor Stinner74f65682019-03-15 15:08:05 +01002206 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002207 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002208 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002209 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2210 if (_PyStatus_EXCEPTION(status)) {
2211 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002212 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002213 }
2214 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002215 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002216 slice.length = cmdline_argv->length - opt_index;
2217 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002218 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2219 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002220 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002221 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002222 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002223
2224 wchar_t *arg0 = NULL;
2225 if (config->run_command != NULL) {
2226 /* Force sys.argv[0] = '-c' */
2227 arg0 = L"-c";
2228 }
2229 else if (config->run_module != NULL) {
2230 /* Force sys.argv[0] = '-m'*/
2231 arg0 = L"-m";
2232 }
2233 if (arg0 != NULL) {
2234 arg0 = _PyMem_RawWcsdup(arg0);
2235 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002236 _PyWideStringList_Clear(&config_argv);
2237 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002238 }
2239
Victor Stinnerfa153762019-03-20 04:25:38 +01002240 PyMem_RawFree(config_argv.items[0]);
2241 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002242 }
2243
Victor Stinner331a6a52019-05-27 16:39:22 +02002244 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002245 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002246 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002247}
2248
2249
Victor Stinner331a6a52019-05-27 16:39:22 +02002250static PyStatus
2251core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002252{
Victor Stinner331a6a52019-05-27 16:39:22 +02002253 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002254
Victor Stinnercab5d072019-05-17 19:01:14 +02002255 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002256 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2257 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002258 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002259 }
2260
Victor Stinner331a6a52019-05-27 16:39:22 +02002261 PyPreConfig preconfig;
Victor Stinner6e128382019-09-28 04:50:43 +02002262
2263 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2264 if (_PyStatus_EXCEPTION(status)) {
2265 return status;
2266 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002267
Victor Stinner331a6a52019-05-27 16:39:22 +02002268 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002269
Victor Stinner331a6a52019-05-27 16:39:22 +02002270 status = _PyPreCmdline_Read(precmdline, &preconfig);
2271 if (_PyStatus_EXCEPTION(status)) {
2272 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002273 }
2274
Victor Stinner331a6a52019-05-27 16:39:22 +02002275 status = _PyPreCmdline_SetConfig(precmdline, config);
2276 if (_PyStatus_EXCEPTION(status)) {
2277 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002278 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002279 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002280}
2281
2282
Victor Stinner331a6a52019-05-27 16:39:22 +02002283static PyStatus
2284config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002285{
Victor Stinner331a6a52019-05-27 16:39:22 +02002286 PyStatus status;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002287 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2288 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2289 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002290
Victor Stinnerae239f62019-05-16 17:02:56 +02002291 if (config->parse_argv < 0) {
2292 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002293 }
Victor Stinner870b0352019-05-17 03:15:12 +02002294
Victor Stinnerfed02e12019-05-17 11:12:09 +02002295 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002296 status = config_init_program_name(config);
2297 if (_PyStatus_EXCEPTION(status)) {
2298 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002299 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002300 }
Victor Stinner2f549082019-03-29 15:13:46 +01002301
Victor Stinnerae239f62019-05-16 17:02:56 +02002302 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002303 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002304 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2305 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002306 goto done;
2307 }
2308
Victor Stinner331a6a52019-05-27 16:39:22 +02002309 status = config_update_argv(config, opt_index);
2310 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002311 goto done;
2312 }
Victor Stinner2f549082019-03-29 15:13:46 +01002313 }
2314
Victor Stinner2f549082019-03-29 15:13:46 +01002315 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002316 status = config_init_env_warnoptions(config, &env_warnoptions);
2317 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002318 goto done;
2319 }
2320 }
2321
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002322 /* Handle early PySys_AddWarnOption() calls */
2323 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2324 if (_PyStatus_EXCEPTION(status)) {
2325 goto done;
2326 }
2327
Victor Stinner331a6a52019-05-27 16:39:22 +02002328 status = config_init_warnoptions(config,
Victor Stinneraf84a882019-08-23 21:16:51 +02002329 &cmdline_warnoptions,
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002330 &env_warnoptions,
2331 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002332 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002333 goto done;
2334 }
2335
Victor Stinner331a6a52019-05-27 16:39:22 +02002336 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002337
2338done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002339 _PyWideStringList_Clear(&cmdline_warnoptions);
2340 _PyWideStringList_Clear(&env_warnoptions);
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002341 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002342 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002343}
2344
2345
Victor Stinner331a6a52019-05-27 16:39:22 +02002346PyStatus
2347_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002348{
Victor Stinner331a6a52019-05-27 16:39:22 +02002349 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2350 if (_PyStatus_EXCEPTION(status)) {
2351 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002352 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002353
Victor Stinner5f38b842019-05-01 02:30:12 +02002354 return _PyArgv_AsWstrList(args, &config->argv);
2355}
2356
2357
Victor Stinner70005ac2019-05-02 15:25:34 -04002358/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2359 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002360PyStatus
2361PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002362{
2363 _PyArgv args = {
2364 .argc = argc,
2365 .use_bytes_argv = 1,
2366 .bytes_argv = argv,
2367 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002368 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002369}
2370
2371
Victor Stinner331a6a52019-05-27 16:39:22 +02002372PyStatus
2373PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002374{
2375 _PyArgv args = {
2376 .argc = argc,
2377 .use_bytes_argv = 0,
2378 .bytes_argv = NULL,
2379 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002380 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002381}
2382
2383
Miss Islington (bot)96f581c2019-07-01 10:39:58 -07002384PyStatus
2385PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2386 Py_ssize_t length, wchar_t **items)
2387{
2388 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2389 if (_PyStatus_EXCEPTION(status)) {
2390 return status;
2391 }
2392
2393 PyWideStringList list2 = {.length = length, .items = items};
2394 if (_PyWideStringList_Copy(list, &list2) < 0) {
2395 return _PyStatus_NO_MEMORY();
2396 }
2397 return _PyStatus_OK();
2398}
2399
2400
Victor Stinner331a6a52019-05-27 16:39:22 +02002401/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002402
2403 * Command line arguments
2404 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002405 * Py_xxx global configuration variables
2406
2407 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002408PyStatus
2409PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002410{
Victor Stinner331a6a52019-05-27 16:39:22 +02002411 PyStatus status;
Miss Islington (bot)c9ed9e62019-09-29 16:58:57 -07002412 PyWideStringList orig_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002413
Victor Stinner331a6a52019-05-27 16:39:22 +02002414 status = _Py_PreInitializeFromConfig(config, NULL);
2415 if (_PyStatus_EXCEPTION(status)) {
2416 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002417 }
2418
Victor Stinner331a6a52019-05-27 16:39:22 +02002419 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002420
Victor Stinner331a6a52019-05-27 16:39:22 +02002421 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2422 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002423 }
2424
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002425 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002426 status = core_read_precmdline(config, &precmdline);
2427 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002428 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002429 }
2430
Victor Stinner870b0352019-05-17 03:15:12 +02002431 assert(config->isolated >= 0);
2432 if (config->isolated) {
2433 config->use_environment = 0;
2434 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002435 }
2436
Victor Stinner331a6a52019-05-27 16:39:22 +02002437 status = config_read_cmdline(config);
2438 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002439 goto done;
2440 }
2441
Victor Stinneraf84a882019-08-23 21:16:51 +02002442 /* Handle early PySys_AddXOption() calls */
2443 status = _PySys_ReadPreinitXOptions(config);
2444 if (_PyStatus_EXCEPTION(status)) {
2445 goto done;
2446 }
2447
Victor Stinner331a6a52019-05-27 16:39:22 +02002448 status = config_read(config);
2449 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002450 goto done;
2451 }
2452
Victor Stinnercab5d072019-05-17 19:01:14 +02002453 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002454 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002455 goto done;
2456 }
2457
2458 /* Check config consistency */
2459 assert(config->isolated >= 0);
2460 assert(config->use_environment >= 0);
2461 assert(config->dev_mode >= 0);
2462 assert(config->install_signal_handlers >= 0);
2463 assert(config->use_hash_seed >= 0);
2464 assert(config->faulthandler >= 0);
2465 assert(config->tracemalloc >= 0);
2466 assert(config->site_import >= 0);
2467 assert(config->bytes_warning >= 0);
2468 assert(config->inspect >= 0);
2469 assert(config->interactive >= 0);
2470 assert(config->optimization_level >= 0);
2471 assert(config->parser_debug >= 0);
2472 assert(config->write_bytecode >= 0);
2473 assert(config->verbose >= 0);
2474 assert(config->quiet >= 0);
2475 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002476 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002477 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002478 assert(config->buffered_stdio >= 0);
2479 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002480 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002481 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2482 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002483 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2484 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2485 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002486 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002487 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002488 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002489 assert(config->executable != NULL);
Steve Dower323e7432019-06-29 14:28:59 -07002490 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002491 assert(config->prefix != NULL);
2492 assert(config->base_prefix != NULL);
2493 assert(config->exec_prefix != NULL);
2494 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002495 }
2496 assert(config->filesystem_encoding != NULL);
2497 assert(config->filesystem_errors != NULL);
2498 assert(config->stdio_encoding != NULL);
2499 assert(config->stdio_errors != NULL);
2500#ifdef MS_WINDOWS
2501 assert(config->legacy_windows_stdio >= 0);
2502#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002503 /* -c and -m options are exclusive */
2504 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002505 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002506 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002507 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002508
Victor Stinner331a6a52019-05-27 16:39:22 +02002509 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002510
2511done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002512 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002513 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002514 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002515}
Victor Stinner1075d162019-03-25 23:19:57 +01002516
2517
2518PyObject*
2519_Py_GetConfigsAsDict(void)
2520{
Victor Stinner331a6a52019-05-27 16:39:22 +02002521 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002522 PyObject *dict = NULL;
2523
Victor Stinner331a6a52019-05-27 16:39:22 +02002524 result = PyDict_New();
2525 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002526 goto error;
2527 }
2528
Victor Stinner331a6a52019-05-27 16:39:22 +02002529 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002530 dict = _Py_GetGlobalVariablesAsDict();
2531 if (dict == NULL) {
2532 goto error;
2533 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002534 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002535 goto error;
2536 }
2537 Py_CLEAR(dict);
2538
2539 /* pre config */
2540 PyInterpreterState *interp = _PyInterpreterState_Get();
Victor Stinner331a6a52019-05-27 16:39:22 +02002541 const PyPreConfig *pre_config = &_PyRuntime.preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002542 dict = _PyPreConfig_AsDict(pre_config);
2543 if (dict == NULL) {
2544 goto error;
2545 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002546 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002547 goto error;
2548 }
2549 Py_CLEAR(dict);
2550
2551 /* core config */
Victor Stinner331a6a52019-05-27 16:39:22 +02002552 const PyConfig *config = &interp->config;
2553 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002554 if (dict == NULL) {
2555 goto error;
2556 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002557 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002558 goto error;
2559 }
2560 Py_CLEAR(dict);
2561
Victor Stinner331a6a52019-05-27 16:39:22 +02002562 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002563
2564error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002565 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002566 Py_XDECREF(dict);
2567 return NULL;
2568}
Victor Stinnerc5c64252019-09-23 15:59:00 +02002569
2570
2571static void
2572init_dump_ascii_wstr(const wchar_t *str)
2573{
2574 if (str == NULL) {
2575 PySys_WriteStderr("(not set)");
2576 return;
2577 }
2578
2579 PySys_WriteStderr("'");
2580 for (; *str != L'\0'; str++) {
2581 wchar_t ch = *str;
2582 if (ch == L'\'') {
2583 PySys_WriteStderr("\\'");
2584 } else if (0x20 <= ch && ch < 0x7f) {
2585 PySys_WriteStderr("%lc", ch);
2586 }
2587 else if (ch <= 0xff) {
2588 PySys_WriteStderr("\\x%02x", ch);
2589 }
2590#if SIZEOF_WCHAR_T > 2
2591 else if (ch > 0xffff) {
2592 PySys_WriteStderr("\\U%08x", ch);
2593 }
2594#endif
2595 else {
2596 PySys_WriteStderr("\\u%04x", ch);
2597 }
2598 }
2599 PySys_WriteStderr("'");
2600}
2601
2602
2603/* Dump the Python path configuration into sys.stderr */
2604void
2605_Py_DumpPathConfig(PyThreadState *tstate)
2606{
2607 PyObject *exc_type, *exc_value, *exc_tb;
2608 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2609
2610 PySys_WriteStderr("Python path configuration:\n");
2611
2612#define DUMP_CONFIG(NAME, FIELD) \
2613 do { \
2614 PySys_WriteStderr(" " NAME " = "); \
2615 init_dump_ascii_wstr(config->FIELD); \
2616 PySys_WriteStderr("\n"); \
2617 } while (0)
2618
2619 PyConfig *config = &tstate->interp->config;
2620 DUMP_CONFIG("PYTHONHOME", home);
2621 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2622 DUMP_CONFIG("program name", program_name);
2623 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2624 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2625 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2626 PySys_WriteStderr(" import site = %i\n", config->site_import);
2627#undef DUMP_CONFIG
2628
2629#define DUMP_SYS(NAME) \
2630 do { \
2631 obj = PySys_GetObject(#NAME); \
2632 PySys_FormatStderr(" sys.%s = ", #NAME); \
2633 if (obj != NULL) { \
2634 PySys_FormatStderr("%A", obj); \
2635 } \
2636 else { \
2637 PySys_WriteStderr("(not set)"); \
2638 } \
2639 PySys_FormatStderr("\n"); \
2640 } while (0)
2641
2642 PyObject *obj;
2643 DUMP_SYS(_base_executable);
2644 DUMP_SYS(base_prefix);
2645 DUMP_SYS(base_exec_prefix);
2646 DUMP_SYS(executable);
2647 DUMP_SYS(prefix);
2648 DUMP_SYS(exec_prefix);
2649#undef DUMP_SYS
2650
2651 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2652 if (sys_path != NULL && PyList_Check(sys_path)) {
2653 PySys_WriteStderr(" sys.path = [\n");
2654 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2655 for (Py_ssize_t i=0; i < len; i++) {
2656 PyObject *path = PyList_GET_ITEM(sys_path, i);
2657 PySys_FormatStderr(" %A,\n", path);
2658 }
2659 PySys_WriteStderr(" ]\n");
2660 }
2661
2662 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2663}