blob: 9a784c75116aaa3197e636b1b6d749576594c4ee [file] [log] [blame]
Victor Stinner6c785c02018-08-01 17:56:14 +02001#include "Python.h"
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002#include "osdefs.h" /* DELIM */
Victor Stinner9fc57a32018-11-07 00:44:03 +01003#include "pycore_fileutils.h"
Victor Stinner95e2cbf2019-03-01 16:25:19 +01004#include "pycore_getopt.h"
Victor Stinnerfcdb0272019-09-23 14:45:47 +02005#include "pycore_initconfig.h"
6#include "pycore_pathconfig.h"
7#include "pycore_pyerrors.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01008#include "pycore_pylifecycle.h"
9#include "pycore_pymem.h"
Victor Stinner6d5ee972019-03-23 12:05:43 +010010#include "pycore_pystate.h" /* _PyRuntime */
Victor Stinner95e2cbf2019-03-01 16:25:19 +010011#include <locale.h> /* setlocale() */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020012#ifdef HAVE_LANGINFO_H
Victor Stinner95e2cbf2019-03-01 16:25:19 +010013# include <langinfo.h> /* nl_langinfo(CODESET) */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020014#endif
Victor Stinner95e2cbf2019-03-01 16:25:19 +010015#if defined(MS_WINDOWS) || defined(__CYGWIN__)
16# include <windows.h> /* GetACP() */
17# ifdef HAVE_IO_H
18# include <io.h>
19# endif
20# ifdef HAVE_FCNTL_H
21# include <fcntl.h> /* O_BINARY */
22# endif
Victor Stinnerb2457ef2018-08-29 13:25:36 +020023#endif
24
Victor Stinner6c785c02018-08-01 17:56:14 +020025
Victor Stinner95e2cbf2019-03-01 16:25:19 +010026/* --- Command line options --------------------------------------- */
27
Victor Stinner95e2cbf2019-03-01 16:25:19 +010028/* Short usage message (with %s for argv0) */
29static const char usage_line[] =
30"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
31
32/* Long usage message, split into parts < 512 bytes */
33static const char usage_1[] = "\
34Options and arguments (and corresponding environment variables):\n\
35-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
36 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
37-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
38-c cmd : program passed in as string (terminates option list)\n\
39-d : debug output from parser; also PYTHONDEBUG=x\n\
40-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
41-h : print this help message and exit (also --help)\n\
42";
43static const char usage_2[] = "\
44-i : inspect interactively after running script; forces a prompt even\n\
45 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
46-I : isolate Python from the user's environment (implies -E and -s)\n\
47-m mod : run library module as a script (terminates option list)\n\
48-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
49 .pyc extension; also PYTHONOPTIMIZE=x\n\
50-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
51 .pyc extension\n\
52-q : don't print version and copyright messages on interactive startup\n\
53-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
54-S : don't imply 'import site' on initialization\n\
55";
56static const char usage_3[] = "\
57-u : force the stdout and stderr streams to be unbuffered;\n\
58 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
59-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
60 can be supplied multiple times to increase verbosity\n\
61-V : print the Python version number and exit (also --version)\n\
62 when given twice, print more information about the build\n\
63-W arg : warning control; arg is action:message:category:module:lineno\n\
64 also PYTHONWARNINGS=arg\n\
65-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +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"
Inada Naoki95826c72019-12-14 14:27:32 +0900114"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"
Serhiy Storchakae9c90aa2019-08-24 12:49:27 +0300119" 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
Victor Stinnerfb4ae152019-09-30 01:40:17 +0200308 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
Victor Stinner3842f292019-08-23 16:57:54 +0100333PyWideStringList_Insert(PyWideStringList *list,
334 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100335{
Victor Stinner3842f292019-08-23 16:57:54 +0100336 Py_ssize_t len = list->length;
337 if (len == PY_SSIZE_T_MAX) {
Min ho Kim96e12d52019-07-22 06:12:33 +1000338 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200339 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100340 }
Victor Stinner3842f292019-08-23 16:57:54 +0100341 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
Victor Stinner3842f292019-08-23 16:57:54 +0100353 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
Victor Stinner3842f292019-08-23 16:57:54 +0100360 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
Victor Stinner3842f292019-08-23 16:57:54 +0100374PyWideStringList_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 Stinner441b10c2019-09-28 04:28:35 +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 Dower9048c492019-06-29 10:34:11 -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
Victor Stinner8462a492019-10-01 12:06:16 +0200604void
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 Stinner441b10c2019-09-28 04:28:35 +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
Victor Stinner8462a492019-10-01 12:06:16 +0200641static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200642config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200643{
Victor Stinner8462a492019-10-01 12:06:16 +0200644 _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
Victor Stinner8462a492019-10-01 12:06:16 +0200666void
Victor Stinner331a6a52019-05-27 16:39:22 +0200667PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200668{
Victor Stinner8462a492019-10-01 12:06:16 +0200669 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
Victor Stinner8462a492019-10-01 12:06:16 +0200677void
Victor Stinner331a6a52019-05-27 16:39:22 +0200678PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200679{
Victor Stinner8462a492019-10-01 12:06:16 +0200680 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 Stinner441b10c2019-09-28 04:28:35 +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 { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200786 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 Dower9048c492019-06-29 10:34:11 -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 Dower9048c492019-06-29 10:34:11 -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.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001122 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001123 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
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002082warnoptions_append(PyConfig *config, PyWideStringList *options,
2083 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002084{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002085 /* 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 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002093 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,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002121 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;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002125 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002126
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002127 /* 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
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002130 * - 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 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002138 * 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) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002145 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002146 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002147 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002148 }
2149 }
2150
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002151 status = warnoptions_extend(config, &options, env_warnoptions);
2152 if (_PyStatus_EXCEPTION(status)) {
2153 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002154 }
2155
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002156 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 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002173 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002174 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002175 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002176 }
2177 }
Victor Stinner120b7072019-08-23 18:03:08 +01002178
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002179 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002180 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002181 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002182 }
2183
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002184 /* 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();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002193
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;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002204 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 }
Victor Stinner3939c322019-06-25 15:02:43 +02002233
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002234 if (arg0 != NULL) {
2235 arg0 = _PyMem_RawWcsdup(arg0);
2236 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002237 _PyWideStringList_Clear(&config_argv);
2238 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002239 }
2240
Victor Stinnerfa153762019-03-20 04:25:38 +01002241 PyMem_RawFree(config_argv.items[0]);
2242 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002243 }
2244
Victor Stinner331a6a52019-05-27 16:39:22 +02002245 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002246 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002247 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002248}
2249
2250
Victor Stinner331a6a52019-05-27 16:39:22 +02002251static PyStatus
2252core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002253{
Victor Stinner331a6a52019-05-27 16:39:22 +02002254 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002255
Victor Stinnercab5d072019-05-17 19:01:14 +02002256 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002257 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2258 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002259 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002260 }
2261
Victor Stinner331a6a52019-05-27 16:39:22 +02002262 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002263
2264 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2265 if (_PyStatus_EXCEPTION(status)) {
2266 return status;
2267 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002268
Victor Stinner331a6a52019-05-27 16:39:22 +02002269 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002270
Victor Stinner331a6a52019-05-27 16:39:22 +02002271 status = _PyPreCmdline_Read(precmdline, &preconfig);
2272 if (_PyStatus_EXCEPTION(status)) {
2273 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002274 }
2275
Victor Stinner331a6a52019-05-27 16:39:22 +02002276 status = _PyPreCmdline_SetConfig(precmdline, config);
2277 if (_PyStatus_EXCEPTION(status)) {
2278 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002279 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002280 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002281}
2282
2283
Victor Stinner3939c322019-06-25 15:02:43 +02002284/* Get run_filename absolute path */
2285static PyStatus
2286config_run_filename_abspath(PyConfig *config)
2287{
2288 if (!config->run_filename) {
2289 return _PyStatus_OK();
2290 }
2291
2292#ifndef MS_WINDOWS
2293 if (_Py_isabs(config->run_filename)) {
2294 /* path is already absolute */
2295 return _PyStatus_OK();
2296 }
2297#endif
2298
2299 wchar_t *abs_filename;
2300 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2301 /* failed to get the absolute path of the command line filename:
2302 ignore the error, keep the relative path */
2303 return _PyStatus_OK();
2304 }
2305 if (abs_filename == NULL) {
2306 return _PyStatus_NO_MEMORY();
2307 }
2308
2309 PyMem_RawFree(config->run_filename);
2310 config->run_filename = abs_filename;
2311 return _PyStatus_OK();
2312}
2313
2314
Victor Stinner331a6a52019-05-27 16:39:22 +02002315static PyStatus
2316config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002317{
Victor Stinner331a6a52019-05-27 16:39:22 +02002318 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002319 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2320 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2321 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002322
Victor Stinnerae239f62019-05-16 17:02:56 +02002323 if (config->parse_argv < 0) {
2324 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002325 }
Victor Stinner870b0352019-05-17 03:15:12 +02002326
Victor Stinnerfed02e12019-05-17 11:12:09 +02002327 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002328 status = config_init_program_name(config);
2329 if (_PyStatus_EXCEPTION(status)) {
2330 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002331 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002332 }
Victor Stinner2f549082019-03-29 15:13:46 +01002333
Victor Stinnerae239f62019-05-16 17:02:56 +02002334 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002335 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002336 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2337 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002338 goto done;
2339 }
2340
Victor Stinner3939c322019-06-25 15:02:43 +02002341 status = config_run_filename_abspath(config);
2342 if (_PyStatus_EXCEPTION(status)) {
2343 goto done;
2344 }
2345
Victor Stinner331a6a52019-05-27 16:39:22 +02002346 status = config_update_argv(config, opt_index);
2347 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002348 goto done;
2349 }
Victor Stinner2f549082019-03-29 15:13:46 +01002350 }
Victor Stinner3939c322019-06-25 15:02:43 +02002351 else {
2352 status = config_run_filename_abspath(config);
2353 if (_PyStatus_EXCEPTION(status)) {
2354 goto done;
2355 }
2356 }
Victor Stinner2f549082019-03-29 15:13:46 +01002357
Victor Stinner2f549082019-03-29 15:13:46 +01002358 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002359 status = config_init_env_warnoptions(config, &env_warnoptions);
2360 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002361 goto done;
2362 }
2363 }
2364
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002365 /* Handle early PySys_AddWarnOption() calls */
2366 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2367 if (_PyStatus_EXCEPTION(status)) {
2368 goto done;
2369 }
2370
Victor Stinner331a6a52019-05-27 16:39:22 +02002371 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002372 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002373 &env_warnoptions,
2374 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002375 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002376 goto done;
2377 }
2378
Victor Stinner331a6a52019-05-27 16:39:22 +02002379 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002380
2381done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002382 _PyWideStringList_Clear(&cmdline_warnoptions);
2383 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002384 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002385 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002386}
2387
2388
Victor Stinner331a6a52019-05-27 16:39:22 +02002389PyStatus
2390_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002391{
Victor Stinner331a6a52019-05-27 16:39:22 +02002392 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2393 if (_PyStatus_EXCEPTION(status)) {
2394 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002395 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002396
Victor Stinner5f38b842019-05-01 02:30:12 +02002397 return _PyArgv_AsWstrList(args, &config->argv);
2398}
2399
2400
Victor Stinner70005ac2019-05-02 15:25:34 -04002401/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2402 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002403PyStatus
2404PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002405{
2406 _PyArgv args = {
2407 .argc = argc,
2408 .use_bytes_argv = 1,
2409 .bytes_argv = argv,
2410 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002411 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002412}
2413
2414
Victor Stinner331a6a52019-05-27 16:39:22 +02002415PyStatus
2416PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002417{
2418 _PyArgv args = {
2419 .argc = argc,
2420 .use_bytes_argv = 0,
2421 .bytes_argv = NULL,
2422 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002423 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002424}
2425
2426
Victor Stinner36242fd2019-07-01 19:13:50 +02002427PyStatus
2428PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2429 Py_ssize_t length, wchar_t **items)
2430{
2431 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2432 if (_PyStatus_EXCEPTION(status)) {
2433 return status;
2434 }
2435
2436 PyWideStringList list2 = {.length = length, .items = items};
2437 if (_PyWideStringList_Copy(list, &list2) < 0) {
2438 return _PyStatus_NO_MEMORY();
2439 }
2440 return _PyStatus_OK();
2441}
2442
2443
Victor Stinner331a6a52019-05-27 16:39:22 +02002444/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002445
2446 * Command line arguments
2447 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002448 * Py_xxx global configuration variables
2449
2450 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002451PyStatus
2452PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002453{
Victor Stinner331a6a52019-05-27 16:39:22 +02002454 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002455 PyWideStringList orig_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002456
Victor Stinner331a6a52019-05-27 16:39:22 +02002457 status = _Py_PreInitializeFromConfig(config, NULL);
2458 if (_PyStatus_EXCEPTION(status)) {
2459 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002460 }
2461
Victor Stinner331a6a52019-05-27 16:39:22 +02002462 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002463
Victor Stinner331a6a52019-05-27 16:39:22 +02002464 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2465 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002466 }
2467
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002468 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002469 status = core_read_precmdline(config, &precmdline);
2470 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002471 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002472 }
2473
Victor Stinner870b0352019-05-17 03:15:12 +02002474 assert(config->isolated >= 0);
2475 if (config->isolated) {
2476 config->use_environment = 0;
2477 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002478 }
2479
Victor Stinner331a6a52019-05-27 16:39:22 +02002480 status = config_read_cmdline(config);
2481 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002482 goto done;
2483 }
2484
Victor Stinner120b7072019-08-23 18:03:08 +01002485 /* Handle early PySys_AddXOption() calls */
2486 status = _PySys_ReadPreinitXOptions(config);
2487 if (_PyStatus_EXCEPTION(status)) {
2488 goto done;
2489 }
2490
Victor Stinner331a6a52019-05-27 16:39:22 +02002491 status = config_read(config);
2492 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002493 goto done;
2494 }
2495
Victor Stinnercab5d072019-05-17 19:01:14 +02002496 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002497 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002498 goto done;
2499 }
2500
2501 /* Check config consistency */
2502 assert(config->isolated >= 0);
2503 assert(config->use_environment >= 0);
2504 assert(config->dev_mode >= 0);
2505 assert(config->install_signal_handlers >= 0);
2506 assert(config->use_hash_seed >= 0);
2507 assert(config->faulthandler >= 0);
2508 assert(config->tracemalloc >= 0);
2509 assert(config->site_import >= 0);
2510 assert(config->bytes_warning >= 0);
2511 assert(config->inspect >= 0);
2512 assert(config->interactive >= 0);
2513 assert(config->optimization_level >= 0);
2514 assert(config->parser_debug >= 0);
2515 assert(config->write_bytecode >= 0);
2516 assert(config->verbose >= 0);
2517 assert(config->quiet >= 0);
2518 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002519 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002520 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002521 assert(config->buffered_stdio >= 0);
2522 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002523 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002524 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2525 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002526 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2527 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2528 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002529 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002530 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002531 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002532 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002533 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002534 assert(config->prefix != NULL);
2535 assert(config->base_prefix != NULL);
2536 assert(config->exec_prefix != NULL);
2537 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002538 }
2539 assert(config->filesystem_encoding != NULL);
2540 assert(config->filesystem_errors != NULL);
2541 assert(config->stdio_encoding != NULL);
2542 assert(config->stdio_errors != NULL);
2543#ifdef MS_WINDOWS
2544 assert(config->legacy_windows_stdio >= 0);
2545#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002546 /* -c and -m options are exclusive */
2547 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002548 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002549 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002550 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002551
Victor Stinner331a6a52019-05-27 16:39:22 +02002552 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002553
2554done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002555 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002556 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002557 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002558}
Victor Stinner1075d162019-03-25 23:19:57 +01002559
2560
2561PyObject*
2562_Py_GetConfigsAsDict(void)
2563{
Victor Stinner331a6a52019-05-27 16:39:22 +02002564 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002565 PyObject *dict = NULL;
2566
Victor Stinner331a6a52019-05-27 16:39:22 +02002567 result = PyDict_New();
2568 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002569 goto error;
2570 }
2571
Victor Stinner331a6a52019-05-27 16:39:22 +02002572 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002573 dict = _Py_GetGlobalVariablesAsDict();
2574 if (dict == NULL) {
2575 goto error;
2576 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002577 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002578 goto error;
2579 }
2580 Py_CLEAR(dict);
2581
2582 /* pre config */
2583 PyInterpreterState *interp = _PyInterpreterState_Get();
Victor Stinner331a6a52019-05-27 16:39:22 +02002584 const PyPreConfig *pre_config = &_PyRuntime.preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002585 dict = _PyPreConfig_AsDict(pre_config);
2586 if (dict == NULL) {
2587 goto error;
2588 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002589 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002590 goto error;
2591 }
2592 Py_CLEAR(dict);
2593
2594 /* core config */
Victor Stinner331a6a52019-05-27 16:39:22 +02002595 const PyConfig *config = &interp->config;
2596 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002597 if (dict == NULL) {
2598 goto error;
2599 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002600 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002601 goto error;
2602 }
2603 Py_CLEAR(dict);
2604
Victor Stinner331a6a52019-05-27 16:39:22 +02002605 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002606
2607error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002608 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002609 Py_XDECREF(dict);
2610 return NULL;
2611}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002612
2613
2614static void
2615init_dump_ascii_wstr(const wchar_t *str)
2616{
2617 if (str == NULL) {
2618 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002619 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002620 }
2621
2622 PySys_WriteStderr("'");
2623 for (; *str != L'\0'; str++) {
2624 wchar_t ch = *str;
2625 if (ch == L'\'') {
2626 PySys_WriteStderr("\\'");
2627 } else if (0x20 <= ch && ch < 0x7f) {
2628 PySys_WriteStderr("%lc", ch);
2629 }
2630 else if (ch <= 0xff) {
2631 PySys_WriteStderr("\\x%02x", ch);
2632 }
2633#if SIZEOF_WCHAR_T > 2
2634 else if (ch > 0xffff) {
2635 PySys_WriteStderr("\\U%08x", ch);
2636 }
2637#endif
2638 else {
2639 PySys_WriteStderr("\\u%04x", ch);
2640 }
2641 }
2642 PySys_WriteStderr("'");
2643}
2644
2645
2646/* Dump the Python path configuration into sys.stderr */
2647void
2648_Py_DumpPathConfig(PyThreadState *tstate)
2649{
2650 PyObject *exc_type, *exc_value, *exc_tb;
2651 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2652
2653 PySys_WriteStderr("Python path configuration:\n");
2654
2655#define DUMP_CONFIG(NAME, FIELD) \
2656 do { \
2657 PySys_WriteStderr(" " NAME " = "); \
2658 init_dump_ascii_wstr(config->FIELD); \
2659 PySys_WriteStderr("\n"); \
2660 } while (0)
2661
2662 PyConfig *config = &tstate->interp->config;
2663 DUMP_CONFIG("PYTHONHOME", home);
2664 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2665 DUMP_CONFIG("program name", program_name);
2666 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2667 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2668 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2669 PySys_WriteStderr(" import site = %i\n", config->site_import);
2670#undef DUMP_CONFIG
2671
2672#define DUMP_SYS(NAME) \
2673 do { \
2674 obj = PySys_GetObject(#NAME); \
2675 PySys_FormatStderr(" sys.%s = ", #NAME); \
2676 if (obj != NULL) { \
2677 PySys_FormatStderr("%A", obj); \
2678 } \
2679 else { \
2680 PySys_WriteStderr("(not set)"); \
2681 } \
2682 PySys_FormatStderr("\n"); \
2683 } while (0)
2684
2685 PyObject *obj;
2686 DUMP_SYS(_base_executable);
2687 DUMP_SYS(base_prefix);
2688 DUMP_SYS(base_exec_prefix);
2689 DUMP_SYS(executable);
2690 DUMP_SYS(prefix);
2691 DUMP_SYS(exec_prefix);
2692#undef DUMP_SYS
2693
2694 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2695 if (sys_path != NULL && PyList_Check(sys_path)) {
2696 PySys_WriteStderr(" sys.path = [\n");
2697 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2698 for (Py_ssize_t i=0; i < len; i++) {
2699 PyObject *path = PyList_GET_ITEM(sys_path, i);
2700 PySys_FormatStderr(" %A,\n", path);
2701 }
2702 PySys_WriteStderr(" ]\n");
2703 }
2704
2705 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2706}