blob: 885525b41848d6895f99504fd8d620c007b80509 [file] [log] [blame]
Victor Stinner6c785c02018-08-01 17:56:14 +02001#include "Python.h"
Victor Stinner4f98f462020-04-15 04:01:58 +02002#include "pycore_fileutils.h" // _Py_HasFileSystemDefaultEncodeErrors
3#include "pycore_getopt.h" // _PyOS_GetOpt()
4#include "pycore_initconfig.h" // _PyStatus_OK()
Victor Stinnere5014be2020-04-14 17:52:15 +02005#include "pycore_interp.h" // _PyInterpreterState.runtime
Victor Stinner4f98f462020-04-15 04:01:58 +02006#include "pycore_pathconfig.h" // _Py_path_config
7#include "pycore_pyerrors.h" // _PyErr_Fetch()
8#include "pycore_pylifecycle.h" // _Py_PreInitializeFromConfig()
Victor Stinnerd9ea5ca2020-04-15 02:57:50 +02009#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
Victor Stinnere5014be2020-04-14 17:52:15 +020010#include "pycore_pystate.h" // _PyThreadState_GET()
Victor Stinner4f98f462020-04-15 04:01:58 +020011
12#include "osdefs.h" // DELIM
Victor Stinnere5014be2020-04-14 17:52:15 +020013#include <locale.h> // setlocale()
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020014#ifdef HAVE_LANGINFO_H
Victor Stinnere5014be2020-04-14 17:52:15 +020015# include <langinfo.h> // nl_langinfo(CODESET)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020016#endif
Victor Stinner95e2cbf2019-03-01 16:25:19 +010017#if defined(MS_WINDOWS) || defined(__CYGWIN__)
Victor Stinnere5014be2020-04-14 17:52:15 +020018# include <windows.h> // GetACP()
Victor Stinner95e2cbf2019-03-01 16:25:19 +010019# ifdef HAVE_IO_H
20# include <io.h>
21# endif
22# ifdef HAVE_FCNTL_H
Victor Stinnere5014be2020-04-14 17:52:15 +020023# include <fcntl.h> // O_BINARY
Victor Stinner95e2cbf2019-03-01 16:25:19 +010024# endif
Victor Stinnerb2457ef2018-08-29 13:25:36 +020025#endif
26
Victor Stinner81750642020-06-08 19:36:13 +020027#ifndef PLATLIBDIR
28# error "PLATLIBDIR macro must be defined"
29#endif
30
Victor Stinner6c785c02018-08-01 17:56:14 +020031
Victor Stinner95e2cbf2019-03-01 16:25:19 +010032/* --- Command line options --------------------------------------- */
33
Victor Stinner95e2cbf2019-03-01 16:25:19 +010034/* Short usage message (with %s for argv0) */
35static const char usage_line[] =
36"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
37
38/* Long usage message, split into parts < 512 bytes */
39static const char usage_1[] = "\
40Options and arguments (and corresponding environment variables):\n\
41-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
42 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
43-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
44-c cmd : program passed in as string (terminates option list)\n\
45-d : debug output from parser; also PYTHONDEBUG=x\n\
46-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
47-h : print this help message and exit (also --help)\n\
48";
49static const char usage_2[] = "\
50-i : inspect interactively after running script; forces a prompt even\n\
51 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
52-I : isolate Python from the user's environment (implies -E and -s)\n\
53-m mod : run library module as a script (terminates option list)\n\
54-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
55 .pyc extension; also PYTHONOPTIMIZE=x\n\
56-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
57 .pyc extension\n\
58-q : don't print version and copyright messages on interactive startup\n\
59-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
60-S : don't imply 'import site' on initialization\n\
61";
62static const char usage_3[] = "\
63-u : force the stdout and stderr streams to be unbuffered;\n\
64 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
65-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
66 can be supplied multiple times to increase verbosity\n\
67-V : print the Python version number and exit (also --version)\n\
68 when given twice, print more information about the build\n\
69-W arg : warning control; arg is action:message:category:module:lineno\n\
70 also PYTHONWARNINGS=arg\n\
71-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000072-X opt : set implementation-specific option. The following options are available:\n\
73\n\
74 -X faulthandler: enable faulthandler\n\
Pablo Galindoc5fc1562020-04-22 23:29:27 +010075 -X oldparser: enable the traditional LL(1) parser; also PYTHONOLDPARSER\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000076 -X showrefcount: output the total reference count and number of used\n\
77 memory blocks when the program finishes or after each statement in the\n\
78 interactive interpreter. This only works on debug builds\n\
79 -X tracemalloc: start tracing Python memory allocations using the\n\
80 tracemalloc module. By default, only the most recent frame is stored in a\n\
81 traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\
82 traceback limit of NFRAME frames\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000083 -X importtime: show how long each import takes. It shows module name,\n\
84 cumulative time (including nested imports) and self time (excluding\n\
85 nested imports). Note that its output may be broken in multi-threaded\n\
86 application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
87 -X dev: enable CPythons development mode”, introducing additional runtime\n\
88 checks which are too expensive to be enabled by default. Effect of the\n\
89 developer mode:\n\
90 * Add default warning filter, as -W default\n\
91 * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\
92 * Enable the faulthandler module to dump the Python traceback on a crash\n\
93 * Enable asyncio debug mode\n\
94 * Set the dev_mode attribute of sys.flags to True\n\
95 * io.IOBase destructor logs close() exceptions\n\
96 -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\
97 locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\
98 otherwise activate automatically)\n\
99 -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
100 given directory instead of to the code tree\n\
101\n\
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100102--check-hash-based-pycs always|default|never:\n\
103 control how Python invalidates hash-based .pyc files\n\
104";
105static const char usage_4[] = "\
106file : program read from script file\n\
107- : program read from stdin (default; interactive mode if a tty)\n\
108arg ...: arguments passed to program in sys.argv[1:]\n\n\
109Other environment variables:\n\
110PYTHONSTARTUP: file executed on interactive startup (no default)\n\
111PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
112 default module search path. The result is sys.path.\n\
113";
114static const char usage_5[] =
115"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
116" The default module search path uses %s.\n"
Victor Stinner81750642020-06-08 19:36:13 +0200117"PYTHONPLATLIBDIR : override sys.platlibdir.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100118"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
Inada Naoki95826c72019-12-14 14:27:32 +0900119"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100120"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
121"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
122static const char usage_6[] =
123"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Serhiy Storchakae9c90aa2019-08-24 12:49:27 +0300124" to seed the hashes of str and bytes objects. It can also be set to an\n"
125" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100126" predictable seed.\n"
127"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
128" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
129" hooks.\n"
130"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
131" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
132" locale coercion and locale compatibility warnings on stderr.\n"
133"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
134" debugger. It can be set to the callable of your debugger of choice.\n"
135"PYTHONDEVMODE: enable the development mode.\n"
136"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
137
138#if defined(MS_WINDOWS)
139# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
140#else
141# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
142#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200143
144
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100145/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200146
Victor Stinner6c785c02018-08-01 17:56:14 +0200147/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200148 stdin and stdout error handler to "surrogateescape". */
149int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200150int Py_DebugFlag = 0; /* Needed by parser.c */
151int Py_VerboseFlag = 0; /* Needed by import.c */
152int Py_QuietFlag = 0; /* Needed by sysmodule.c */
153int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
154int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
155int Py_OptimizeFlag = 0; /* Needed by compile.c */
156int Py_NoSiteFlag = 0; /* Suppress 'import site' */
157int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
158int Py_FrozenFlag = 0; /* Needed by getpath.c */
159int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
160int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
161int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
162int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
163int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
164int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
165#ifdef MS_WINDOWS
166int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
167int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
168#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200169
170
Victor Stinner1075d162019-03-25 23:19:57 +0100171static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100172_Py_GetGlobalVariablesAsDict(void)
173{
174 PyObject *dict, *obj;
175
176 dict = PyDict_New();
177 if (dict == NULL) {
178 return NULL;
179 }
180
181#define SET_ITEM(KEY, EXPR) \
182 do { \
183 obj = (EXPR); \
184 if (obj == NULL) { \
185 return NULL; \
186 } \
187 int res = PyDict_SetItemString(dict, (KEY), obj); \
188 Py_DECREF(obj); \
189 if (res < 0) { \
190 goto fail; \
191 } \
192 } while (0)
193#define SET_ITEM_INT(VAR) \
194 SET_ITEM(#VAR, PyLong_FromLong(VAR))
195#define FROM_STRING(STR) \
196 ((STR != NULL) ? \
197 PyUnicode_FromString(STR) \
198 : (Py_INCREF(Py_None), Py_None))
199#define SET_ITEM_STR(VAR) \
200 SET_ITEM(#VAR, FROM_STRING(VAR))
201
202 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
203 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
204 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
205 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
206
207 SET_ITEM_INT(Py_UTF8Mode);
208 SET_ITEM_INT(Py_DebugFlag);
209 SET_ITEM_INT(Py_VerboseFlag);
210 SET_ITEM_INT(Py_QuietFlag);
211 SET_ITEM_INT(Py_InteractiveFlag);
212 SET_ITEM_INT(Py_InspectFlag);
213
214 SET_ITEM_INT(Py_OptimizeFlag);
215 SET_ITEM_INT(Py_NoSiteFlag);
216 SET_ITEM_INT(Py_BytesWarningFlag);
217 SET_ITEM_INT(Py_FrozenFlag);
218 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
219 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
220 SET_ITEM_INT(Py_NoUserSiteDirectory);
221 SET_ITEM_INT(Py_UnbufferedStdioFlag);
222 SET_ITEM_INT(Py_HashRandomizationFlag);
223 SET_ITEM_INT(Py_IsolatedFlag);
224
225#ifdef MS_WINDOWS
226 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
227 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
228#endif
229
230 return dict;
231
232fail:
233 Py_DECREF(dict);
234 return NULL;
235
236#undef FROM_STRING
237#undef SET_ITEM
238#undef SET_ITEM_INT
239#undef SET_ITEM_STR
240}
241
242
Victor Stinner331a6a52019-05-27 16:39:22 +0200243/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200244
Victor Stinner331a6a52019-05-27 16:39:22 +0200245PyStatus PyStatus_Ok(void)
246{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200247
Victor Stinner331a6a52019-05-27 16:39:22 +0200248PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200249{
Victor Stinner331a6a52019-05-27 16:39:22 +0200250 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner871ff772019-05-17 23:54:00 +0200251 .err_msg = err_msg};
252}
253
Victor Stinner331a6a52019-05-27 16:39:22 +0200254PyStatus PyStatus_NoMemory(void)
255{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200256
Victor Stinner331a6a52019-05-27 16:39:22 +0200257PyStatus PyStatus_Exit(int exitcode)
258{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200259
260
Victor Stinner331a6a52019-05-27 16:39:22 +0200261int PyStatus_IsError(PyStatus status)
262{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200263
Victor Stinner331a6a52019-05-27 16:39:22 +0200264int PyStatus_IsExit(PyStatus status)
265{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200266
Victor Stinner331a6a52019-05-27 16:39:22 +0200267int PyStatus_Exception(PyStatus status)
268{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200269
270
Victor Stinner331a6a52019-05-27 16:39:22 +0200271/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100272
273#ifndef NDEBUG
274int
Victor Stinner331a6a52019-05-27 16:39:22 +0200275_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100276{
277 assert(list->length >= 0);
278 if (list->length != 0) {
279 assert(list->items != NULL);
280 }
281 for (Py_ssize_t i = 0; i < list->length; i++) {
282 assert(list->items[i] != NULL);
283 }
284 return 1;
285}
286#endif /* Py_DEBUG */
287
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100288
Victor Stinner6c785c02018-08-01 17:56:14 +0200289void
Victor Stinner331a6a52019-05-27 16:39:22 +0200290_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200291{
Victor Stinner331a6a52019-05-27 16:39:22 +0200292 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100293 for (Py_ssize_t i=0; i < list->length; i++) {
294 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200295 }
Victor Stinner74f65682019-03-15 15:08:05 +0100296 PyMem_RawFree(list->items);
297 list->length = 0;
298 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200299}
300
301
Victor Stinner74f65682019-03-15 15:08:05 +0100302int
Victor Stinner331a6a52019-05-27 16:39:22 +0200303_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200304{
Victor Stinner331a6a52019-05-27 16:39:22 +0200305 assert(_PyWideStringList_CheckConsistency(list));
306 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100307
308 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200309 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100310 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300311 }
Victor Stinner74f65682019-03-15 15:08:05 +0100312
Victor Stinnerfb4ae152019-09-30 01:40:17 +0200313 PyWideStringList copy = _PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100314
315 size_t size = list2->length * sizeof(list2->items[0]);
316 copy.items = PyMem_RawMalloc(size);
317 if (copy.items == NULL) {
318 return -1;
319 }
320
321 for (Py_ssize_t i=0; i < list2->length; i++) {
322 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
323 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200324 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100325 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200326 }
Victor Stinner74f65682019-03-15 15:08:05 +0100327 copy.items[i] = item;
328 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200329 }
Victor Stinner74f65682019-03-15 15:08:05 +0100330
Victor Stinner331a6a52019-05-27 16:39:22 +0200331 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100332 *list = copy;
333 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200334}
335
336
Victor Stinner331a6a52019-05-27 16:39:22 +0200337PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100338PyWideStringList_Insert(PyWideStringList *list,
339 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100340{
Victor Stinner3842f292019-08-23 16:57:54 +0100341 Py_ssize_t len = list->length;
342 if (len == PY_SSIZE_T_MAX) {
Min ho Kim96e12d52019-07-22 06:12:33 +1000343 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200344 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100345 }
Victor Stinner3842f292019-08-23 16:57:54 +0100346 if (index < 0) {
347 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
348 }
349 if (index > len) {
350 index = len;
351 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100352
Victor Stinner74f65682019-03-15 15:08:05 +0100353 wchar_t *item2 = _PyMem_RawWcsdup(item);
354 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200355 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100356 }
Victor Stinner74f65682019-03-15 15:08:05 +0100357
Victor Stinner3842f292019-08-23 16:57:54 +0100358 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100359 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
360 if (items2 == NULL) {
361 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200362 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100363 }
364
Victor Stinner3842f292019-08-23 16:57:54 +0100365 if (index < len) {
366 memmove(&items2[index + 1],
367 &items2[index],
368 (len - index) * sizeof(items2[0]));
369 }
370
371 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100372 list->items = items2;
373 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200374 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100375}
376
377
Victor Stinner331a6a52019-05-27 16:39:22 +0200378PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100379PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
380{
381 return PyWideStringList_Insert(list, list->length, item);
382}
383
384
385PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200386_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100387{
388 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200389 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
390 if (_PyStatus_EXCEPTION(status)) {
391 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100392 }
393 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200394 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100395}
396
397
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100398static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200399_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100400{
401 for (Py_ssize_t i = 0; i < list->length; i++) {
402 if (wcscmp(list->items[i], item) == 0) {
403 return 1;
404 }
405 }
406 return 0;
407}
408
409
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100410PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200411_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100412{
Victor Stinner331a6a52019-05-27 16:39:22 +0200413 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100414
Victor Stinner74f65682019-03-15 15:08:05 +0100415 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100416 if (pylist == NULL) {
417 return NULL;
418 }
419
Victor Stinner74f65682019-03-15 15:08:05 +0100420 for (Py_ssize_t i = 0; i < list->length; i++) {
421 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
422 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100423 Py_DECREF(pylist);
424 return NULL;
425 }
Victor Stinner74f65682019-03-15 15:08:05 +0100426 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100427 }
428 return pylist;
429}
430
431
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100432/* --- Py_SetStandardStreamEncoding() ----------------------------- */
433
Victor Stinner124b9eb2018-08-29 01:29:06 +0200434/* Helper to allow an embedding application to override the normal
435 * mechanism that attempts to figure out an appropriate IO encoding
436 */
437
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200438static char *_Py_StandardStreamEncoding = NULL;
439static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200440
441int
442Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
443{
444 if (Py_IsInitialized()) {
445 /* This is too late to have any effect */
446 return -1;
447 }
448
449 int res = 0;
450
451 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
452 but Py_Initialize() can change the allocator. Use a known allocator
453 to be able to release the memory later. */
454 PyMemAllocatorEx old_alloc;
455 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
456
457 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
458 * initialised yet.
459 *
460 * However, the raw memory allocators are initialised appropriately
461 * as C static variables, so _PyMem_RawStrdup is OK even though
462 * Py_Initialize hasn't been called yet.
463 */
464 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200465 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200466 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
467 if (!_Py_StandardStreamEncoding) {
468 res = -2;
469 goto done;
470 }
471 }
472 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200473 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200474 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
475 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200476 PyMem_RawFree(_Py_StandardStreamEncoding);
477 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200478 res = -3;
479 goto done;
480 }
481 }
482#ifdef MS_WINDOWS
483 if (_Py_StandardStreamEncoding) {
484 /* Overriding the stream encoding implies legacy streams */
485 Py_LegacyWindowsStdioFlag = 1;
486 }
487#endif
488
489done:
490 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
491
492 return res;
493}
494
495
496void
497_Py_ClearStandardStreamEncoding(void)
498{
499 /* Use the same allocator than Py_SetStandardStreamEncoding() */
500 PyMemAllocatorEx old_alloc;
501 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
502
503 /* We won't need them anymore. */
504 if (_Py_StandardStreamEncoding) {
505 PyMem_RawFree(_Py_StandardStreamEncoding);
506 _Py_StandardStreamEncoding = NULL;
507 }
508 if (_Py_StandardStreamErrors) {
509 PyMem_RawFree(_Py_StandardStreamErrors);
510 _Py_StandardStreamErrors = NULL;
511 }
512
513 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
514}
515
516
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100517/* --- Py_GetArgcArgv() ------------------------------------------- */
518
519/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200520static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100521
522
523void
524_Py_ClearArgcArgv(void)
525{
526 PyMemAllocatorEx old_alloc;
527 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
528
Victor Stinner331a6a52019-05-27 16:39:22 +0200529 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100530
531 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
532}
533
534
Victor Stinner4fffd382019-03-06 01:44:31 +0100535static int
Victor Stinner74f65682019-03-15 15:08:05 +0100536_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100537{
Victor Stinner331a6a52019-05-27 16:39:22 +0200538 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100539 int res;
540
541 PyMemAllocatorEx old_alloc;
542 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
543
Victor Stinner331a6a52019-05-27 16:39:22 +0200544 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100545
546 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
547 return res;
548}
549
550
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100551void
552Py_GetArgcArgv(int *argc, wchar_t ***argv)
553{
Victor Stinner74f65682019-03-15 15:08:05 +0100554 *argc = (int)orig_argv.length;
555 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100556}
557
558
Victor Stinner331a6a52019-05-27 16:39:22 +0200559/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100560
561#define DECODE_LOCALE_ERR(NAME, LEN) \
562 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200563 ? _PyStatus_ERR("cannot decode " NAME) \
564 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100565
Victor Stinner441b10c2019-09-28 04:28:35 +0200566
Victor Stinner6c785c02018-08-01 17:56:14 +0200567/* Free memory allocated in config, but don't clear all attributes */
568void
Victor Stinner331a6a52019-05-27 16:39:22 +0200569PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200570{
571#define CLEAR(ATTR) \
572 do { \
573 PyMem_RawFree(ATTR); \
574 ATTR = NULL; \
575 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200576
577 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200578 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200579 CLEAR(config->home);
580 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200581
Victor Stinner331a6a52019-05-27 16:39:22 +0200582 _PyWideStringList_Clear(&config->argv);
583 _PyWideStringList_Clear(&config->warnoptions);
584 _PyWideStringList_Clear(&config->xoptions);
585 _PyWideStringList_Clear(&config->module_search_paths);
586 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200587
588 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700589 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200590 CLEAR(config->prefix);
591 CLEAR(config->base_prefix);
592 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200593 CLEAR(config->base_exec_prefix);
Victor Stinner81750642020-06-08 19:36:13 +0200594 CLEAR(config->platlibdir);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200595
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200596 CLEAR(config->filesystem_encoding);
597 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200598 CLEAR(config->stdio_encoding);
599 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100600 CLEAR(config->run_command);
601 CLEAR(config->run_module);
602 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400603 CLEAR(config->check_hash_pycs_mode);
Miss Islington (bot)bab08332020-06-15 08:19:06 -0700604
605 _PyWideStringList_Clear(&config->_orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200606#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200607}
608
609
Victor Stinner8462a492019-10-01 12:06:16 +0200610void
Victor Stinner331a6a52019-05-27 16:39:22 +0200611_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200612{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200613 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200614
Victor Stinner022be022019-05-22 23:58:50 +0200615 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200616 config->isolated = -1;
617 config->use_environment = -1;
618 config->dev_mode = -1;
619 config->install_signal_handlers = 1;
620 config->use_hash_seed = -1;
621 config->faulthandler = -1;
622 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200623 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200624 config->parse_argv = 0;
625 config->site_import = -1;
626 config->bytes_warning = -1;
627 config->inspect = -1;
628 config->interactive = -1;
629 config->optimization_level = -1;
630 config->parser_debug= -1;
631 config->write_bytecode = -1;
632 config->verbose = -1;
633 config->quiet = -1;
634 config->user_site_directory = -1;
635 config->configure_c_stdio = 0;
636 config->buffered_stdio = -1;
637 config->_install_importlib = 1;
638 config->check_hash_pycs_mode = NULL;
639 config->pathconfig_warnings = -1;
640 config->_init_main = 1;
Victor Stinner252346a2020-05-01 11:33:44 +0200641 config->_isolated_interpreter = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200642#ifdef MS_WINDOWS
643 config->legacy_windows_stdio = -1;
644#endif
Victor Stinner1def7752020-04-23 03:03:24 +0200645 config->_use_peg_parser = 1;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200646}
647
648
Victor Stinner8462a492019-10-01 12:06:16 +0200649static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200650config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200651{
Victor Stinner8462a492019-10-01 12:06:16 +0200652 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200653
654 config->isolated = 0;
655 config->use_environment = 1;
656 config->site_import = 1;
657 config->bytes_warning = 0;
658 config->inspect = 0;
659 config->interactive = 0;
660 config->optimization_level = 0;
661 config->parser_debug= 0;
662 config->write_bytecode = 1;
663 config->verbose = 0;
664 config->quiet = 0;
665 config->user_site_directory = 1;
666 config->buffered_stdio = 1;
667 config->pathconfig_warnings = 1;
668#ifdef MS_WINDOWS
669 config->legacy_windows_stdio = 0;
670#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200671}
672
673
Victor Stinner8462a492019-10-01 12:06:16 +0200674void
Victor Stinner331a6a52019-05-27 16:39:22 +0200675PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200676{
Victor Stinner8462a492019-10-01 12:06:16 +0200677 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200678
Victor Stinner022be022019-05-22 23:58:50 +0200679 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200680 config->configure_c_stdio = 1;
681 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200682}
683
684
Victor Stinner8462a492019-10-01 12:06:16 +0200685void
Victor Stinner331a6a52019-05-27 16:39:22 +0200686PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200687{
Victor Stinner8462a492019-10-01 12:06:16 +0200688 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200689
Victor Stinner022be022019-05-22 23:58:50 +0200690 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200691 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200692 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200693 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200694 config->dev_mode = 0;
695 config->install_signal_handlers = 0;
696 config->use_hash_seed = 0;
697 config->faulthandler = 0;
698 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200699 config->pathconfig_warnings = 0;
700#ifdef MS_WINDOWS
701 config->legacy_windows_stdio = 0;
702#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200703}
704
705
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200706/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200707PyStatus
708PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200709{
Victor Stinner331a6a52019-05-27 16:39:22 +0200710 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
711 if (_PyStatus_EXCEPTION(status)) {
712 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200713 }
714
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200715 wchar_t *str2;
716 if (str != NULL) {
717 str2 = _PyMem_RawWcsdup(str);
718 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200719 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200720 }
721 }
722 else {
723 str2 = NULL;
724 }
725 PyMem_RawFree(*config_str);
726 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200727 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200728}
729
730
Victor Stinner331a6a52019-05-27 16:39:22 +0200731static PyStatus
732config_set_bytes_string(PyConfig *config, wchar_t **config_str,
733 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200734{
Victor Stinner331a6a52019-05-27 16:39:22 +0200735 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
736 if (_PyStatus_EXCEPTION(status)) {
737 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400738 }
739
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200740 wchar_t *str2;
741 if (str != NULL) {
742 size_t len;
743 str2 = Py_DecodeLocale(str, &len);
744 if (str2 == NULL) {
745 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200746 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200747 }
748 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200749 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200750 }
751 }
752 }
753 else {
754 str2 = NULL;
755 }
756 PyMem_RawFree(*config_str);
757 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200758 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200759}
760
761
Victor Stinner331a6a52019-05-27 16:39:22 +0200762#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
763 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400764
765
Victor Stinner70005ac2019-05-02 15:25:34 -0400766/* Decode str using Py_DecodeLocale() and set the result into *config_str.
767 Pre-initialize Python if needed to ensure that encodings are properly
768 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200769PyStatus
770PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200771 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400772{
Victor Stinner331a6a52019-05-27 16:39:22 +0200773 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400774}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200775
776
Victor Stinner331a6a52019-05-27 16:39:22 +0200777PyStatus
778_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200779{
Victor Stinner331a6a52019-05-27 16:39:22 +0200780 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200781
Victor Stinner331a6a52019-05-27 16:39:22 +0200782 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200783
784#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200785#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200786 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200787 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
788 if (_PyStatus_EXCEPTION(status)) { \
789 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200790 } \
791 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100792#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200793 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200794 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200795 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200796 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200797 } while (0)
798
Victor Stinner6d1c4672019-05-20 11:02:00 +0200799 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100800 COPY_ATTR(isolated);
801 COPY_ATTR(use_environment);
802 COPY_ATTR(dev_mode);
Victor Stinner1def7752020-04-23 03:03:24 +0200803 COPY_ATTR(_use_peg_parser);
Victor Stinner6c785c02018-08-01 17:56:14 +0200804 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200805 COPY_ATTR(use_hash_seed);
806 COPY_ATTR(hash_seed);
807 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200808 COPY_ATTR(faulthandler);
809 COPY_ATTR(tracemalloc);
810 COPY_ATTR(import_time);
811 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200812 COPY_ATTR(dump_refs);
813 COPY_ATTR(malloc_stats);
814
Victor Stinner124b9eb2018-08-29 01:29:06 +0200815 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200816 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200817 COPY_WSTR_ATTR(home);
818 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200819
Victor Stinnerae239f62019-05-16 17:02:56 +0200820 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100821 COPY_WSTRLIST(argv);
822 COPY_WSTRLIST(warnoptions);
823 COPY_WSTRLIST(xoptions);
824 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200825 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200826
Victor Stinner124b9eb2018-08-29 01:29:06 +0200827 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700828 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200829 COPY_WSTR_ATTR(prefix);
830 COPY_WSTR_ATTR(base_prefix);
831 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200832 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner81750642020-06-08 19:36:13 +0200833 COPY_WSTR_ATTR(platlibdir);
Victor Stinner6c785c02018-08-01 17:56:14 +0200834
Victor Stinner6c785c02018-08-01 17:56:14 +0200835 COPY_ATTR(site_import);
836 COPY_ATTR(bytes_warning);
837 COPY_ATTR(inspect);
838 COPY_ATTR(interactive);
839 COPY_ATTR(optimization_level);
840 COPY_ATTR(parser_debug);
841 COPY_ATTR(write_bytecode);
842 COPY_ATTR(verbose);
843 COPY_ATTR(quiet);
844 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200845 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200846 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400847 COPY_WSTR_ATTR(filesystem_encoding);
848 COPY_WSTR_ATTR(filesystem_errors);
849 COPY_WSTR_ATTR(stdio_encoding);
850 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200851#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200852 COPY_ATTR(legacy_windows_stdio);
853#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100854 COPY_ATTR(skip_source_first_line);
855 COPY_WSTR_ATTR(run_command);
856 COPY_WSTR_ATTR(run_module);
857 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400858 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200859 COPY_ATTR(pathconfig_warnings);
860 COPY_ATTR(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200861 COPY_ATTR(_isolated_interpreter);
Victor Stinnerdedaac02020-06-08 18:44:50 +0200862 COPY_WSTRLIST(_orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200863
864#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200865#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200866#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200867 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200868}
869
870
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100871static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200872config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100873{
874 PyObject *dict;
875
876 dict = PyDict_New();
877 if (dict == NULL) {
878 return NULL;
879 }
880
881#define SET_ITEM(KEY, EXPR) \
882 do { \
883 PyObject *obj = (EXPR); \
884 if (obj == NULL) { \
885 goto fail; \
886 } \
887 int res = PyDict_SetItemString(dict, (KEY), obj); \
888 Py_DECREF(obj); \
889 if (res < 0) { \
890 goto fail; \
891 } \
892 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100893#define SET_ITEM_INT(ATTR) \
894 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
895#define SET_ITEM_UINT(ATTR) \
896 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100897#define FROM_WSTRING(STR) \
898 ((STR != NULL) ? \
899 PyUnicode_FromWideChar(STR, -1) \
900 : (Py_INCREF(Py_None), Py_None))
901#define SET_ITEM_WSTR(ATTR) \
902 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
903#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200904 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100905
Victor Stinner6d1c4672019-05-20 11:02:00 +0200906 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100907 SET_ITEM_INT(isolated);
908 SET_ITEM_INT(use_environment);
909 SET_ITEM_INT(dev_mode);
Victor Stinner1def7752020-04-23 03:03:24 +0200910 SET_ITEM_INT(_use_peg_parser);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100911 SET_ITEM_INT(install_signal_handlers);
912 SET_ITEM_INT(use_hash_seed);
913 SET_ITEM_UINT(hash_seed);
914 SET_ITEM_INT(faulthandler);
915 SET_ITEM_INT(tracemalloc);
916 SET_ITEM_INT(import_time);
917 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100918 SET_ITEM_INT(dump_refs);
919 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400920 SET_ITEM_WSTR(filesystem_encoding);
921 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100922 SET_ITEM_WSTR(pycache_prefix);
923 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200924 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100925 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100926 SET_ITEM_WSTRLIST(xoptions);
927 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200928 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100929 SET_ITEM_WSTR(home);
930 SET_ITEM_WSTRLIST(module_search_paths);
931 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700932 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100933 SET_ITEM_WSTR(prefix);
934 SET_ITEM_WSTR(base_prefix);
935 SET_ITEM_WSTR(exec_prefix);
936 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinner81750642020-06-08 19:36:13 +0200937 SET_ITEM_WSTR(platlibdir);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100938 SET_ITEM_INT(site_import);
939 SET_ITEM_INT(bytes_warning);
940 SET_ITEM_INT(inspect);
941 SET_ITEM_INT(interactive);
942 SET_ITEM_INT(optimization_level);
943 SET_ITEM_INT(parser_debug);
944 SET_ITEM_INT(write_bytecode);
945 SET_ITEM_INT(verbose);
946 SET_ITEM_INT(quiet);
947 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200948 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100949 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400950 SET_ITEM_WSTR(stdio_encoding);
951 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100952#ifdef MS_WINDOWS
953 SET_ITEM_INT(legacy_windows_stdio);
954#endif
955 SET_ITEM_INT(skip_source_first_line);
956 SET_ITEM_WSTR(run_command);
957 SET_ITEM_WSTR(run_module);
958 SET_ITEM_WSTR(run_filename);
959 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400960 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200961 SET_ITEM_INT(pathconfig_warnings);
962 SET_ITEM_INT(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200963 SET_ITEM_INT(_isolated_interpreter);
Victor Stinnerdedaac02020-06-08 18:44:50 +0200964 SET_ITEM_WSTRLIST(_orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100965
966 return dict;
967
968fail:
969 Py_DECREF(dict);
970 return NULL;
971
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100972#undef FROM_WSTRING
973#undef SET_ITEM
974#undef SET_ITEM_INT
975#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100976#undef SET_ITEM_WSTR
977#undef SET_ITEM_WSTRLIST
978}
979
980
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100981static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200982config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200983{
Victor Stinner20004952019-03-26 02:31:11 +0100984 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200985}
986
987
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100988/* Get a copy of the environment variable as wchar_t*.
989 Return 0 on success, but *dest can be NULL.
990 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200991static PyStatus
992config_get_env_dup(PyConfig *config,
993 wchar_t **dest,
994 wchar_t *wname, char *name,
995 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200996{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200997 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100998 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200999
Victor Stinner20004952019-03-26 02:31:11 +01001000 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001001 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001002 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001003 }
1004
1005#ifdef MS_WINDOWS
1006 const wchar_t *var = _wgetenv(wname);
1007 if (!var || var[0] == '\0') {
1008 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001009 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001010 }
1011
Victor Stinner331a6a52019-05-27 16:39:22 +02001012 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +02001013#else
1014 const char *var = getenv(name);
1015 if (!var || var[0] == '\0') {
1016 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001017 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001018 }
1019
Victor Stinner331a6a52019-05-27 16:39:22 +02001020 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001021#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001022}
1023
1024
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001025#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001026 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001027
1028
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001029static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001030config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001031{
Victor Stinner022be022019-05-22 23:58:50 +02001032 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1033 /* Python and Isolated configuration ignore global variables */
1034 return;
1035 }
1036
Victor Stinner6c785c02018-08-01 17:56:14 +02001037#define COPY_FLAG(ATTR, VALUE) \
1038 if (config->ATTR == -1) { \
1039 config->ATTR = VALUE; \
1040 }
1041#define COPY_NOT_FLAG(ATTR, VALUE) \
1042 if (config->ATTR == -1) { \
1043 config->ATTR = !(VALUE); \
1044 }
1045
Victor Stinner20004952019-03-26 02:31:11 +01001046 COPY_FLAG(isolated, Py_IsolatedFlag);
1047 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001048 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1049 COPY_FLAG(inspect, Py_InspectFlag);
1050 COPY_FLAG(interactive, Py_InteractiveFlag);
1051 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1052 COPY_FLAG(parser_debug, Py_DebugFlag);
1053 COPY_FLAG(verbose, Py_VerboseFlag);
1054 COPY_FLAG(quiet, Py_QuietFlag);
1055#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001056 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1057#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001058 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001059
Victor Stinner6c785c02018-08-01 17:56:14 +02001060 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1061 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1062 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1063 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1064
Victor Stinner6c785c02018-08-01 17:56:14 +02001065#undef COPY_FLAG
1066#undef COPY_NOT_FLAG
1067}
1068
1069
1070/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001071static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001072config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001073{
1074#define COPY_FLAG(ATTR, VAR) \
1075 if (config->ATTR != -1) { \
1076 VAR = config->ATTR; \
1077 }
1078#define COPY_NOT_FLAG(ATTR, VAR) \
1079 if (config->ATTR != -1) { \
1080 VAR = !config->ATTR; \
1081 }
1082
Victor Stinner20004952019-03-26 02:31:11 +01001083 COPY_FLAG(isolated, Py_IsolatedFlag);
1084 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001085 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1086 COPY_FLAG(inspect, Py_InspectFlag);
1087 COPY_FLAG(interactive, Py_InteractiveFlag);
1088 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1089 COPY_FLAG(parser_debug, Py_DebugFlag);
1090 COPY_FLAG(verbose, Py_VerboseFlag);
1091 COPY_FLAG(quiet, Py_QuietFlag);
1092#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001093 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1094#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001095 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001096
Victor Stinner6c785c02018-08-01 17:56:14 +02001097 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1098 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1099 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1100 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1101
Victor Stinner6c785c02018-08-01 17:56:14 +02001102 /* Random or non-zero hash seed */
1103 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1104 config->hash_seed != 0);
1105
1106#undef COPY_FLAG
1107#undef COPY_NOT_FLAG
1108}
1109
1110
1111/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1112 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001113static PyStatus
1114config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001115{
Victor Stinner331a6a52019-05-27 16:39:22 +02001116 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001117
Victor Stinner6c785c02018-08-01 17:56:14 +02001118 /* If Py_SetProgramName() was called, use its value */
1119 const wchar_t *program_name = _Py_path_config.program_name;
1120 if (program_name != NULL) {
1121 config->program_name = _PyMem_RawWcsdup(program_name);
1122 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001123 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001124 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001125 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001126 }
1127
1128#ifdef __APPLE__
1129 /* On MacOS X, when the Python interpreter is embedded in an
1130 application bundle, it gets executed by a bootstrapping script
1131 that does os.execve() with an argv[0] that's different from the
1132 actual Python executable. This is needed to keep the Finder happy,
1133 or rather, to work around Apple's overly strict requirements of
1134 the process name. However, we still need a usable sys.executable,
1135 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001136 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001137 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001138 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001139 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001140 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1141 "PYTHONEXECUTABLE environment variable");
1142 if (_PyStatus_EXCEPTION(status)) {
1143 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001144 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001145 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001146 }
1147#ifdef WITH_NEXT_FRAMEWORK
1148 else {
1149 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1150 if (pyvenv_launcher && *pyvenv_launcher) {
1151 /* Used by Mac/Tools/pythonw.c to forward
1152 * the argv0 of the stub executable
1153 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001154 status = CONFIG_SET_BYTES_STR(config,
1155 &config->program_name,
1156 pyvenv_launcher,
1157 "__PYVENV_LAUNCHER__ environment variable");
1158 if (_PyStatus_EXCEPTION(status)) {
1159 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001160 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001161
1162 /*
1163 * This environment variable is used to communicate between
1164 * the stub launcher and the real interpreter and isn't needed
1165 * beyond this point.
1166 *
1167 * Clean up to avoid problems when launching other programs
1168 * later on.
1169 */
1170 (void)unsetenv("__PYVENV_LAUNCHER__");
1171
Victor Stinner331a6a52019-05-27 16:39:22 +02001172 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001173 }
1174 }
1175#endif /* WITH_NEXT_FRAMEWORK */
1176#endif /* __APPLE__ */
1177
Victor Stinnerfed02e12019-05-17 11:12:09 +02001178 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001179 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001180 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1181 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1182 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001183 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001184 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001185 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001186 }
1187
Victor Stinnerfed02e12019-05-17 11:12:09 +02001188 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001189#ifdef MS_WINDOWS
1190 const wchar_t *default_program_name = L"python";
1191#else
1192 const wchar_t *default_program_name = L"python3";
1193#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001194 status = PyConfig_SetString(config, &config->program_name,
1195 default_program_name);
1196 if (_PyStatus_EXCEPTION(status)) {
1197 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001198 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001199 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001200}
1201
Victor Stinner331a6a52019-05-27 16:39:22 +02001202static PyStatus
1203config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001204{
1205 assert(config->executable == NULL);
1206
1207 /* If Py_SetProgramFullPath() was called, use its value */
1208 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1209 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001210 PyStatus status = PyConfig_SetString(config,
1211 &config->executable,
1212 program_full_path);
1213 if (_PyStatus_EXCEPTION(status)) {
1214 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001215 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001216 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001217 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001218 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001219}
Victor Stinner6c785c02018-08-01 17:56:14 +02001220
Victor Stinner4fffd382019-03-06 01:44:31 +01001221
Victor Stinner6c785c02018-08-01 17:56:14 +02001222static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001223config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001224{
Victor Stinner74f65682019-03-15 15:08:05 +01001225 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001226}
1227
1228
Victor Stinner331a6a52019-05-27 16:39:22 +02001229static PyStatus
1230config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001231{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001232 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001233
1234 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001235 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001236 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001237 PyStatus status = PyConfig_SetString(config, &config->home, home);
1238 if (_PyStatus_EXCEPTION(status)) {
1239 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001240 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001241 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001242 }
1243
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001244 return CONFIG_GET_ENV_DUP(config, &config->home,
1245 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001246}
1247
1248
Victor Stinner331a6a52019-05-27 16:39:22 +02001249static PyStatus
1250config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001251{
Victor Stinner331a6a52019-05-27 16:39:22 +02001252 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001253
1254 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1255 /* Convert a text seed to a numeric one */
1256 if (seed_text && strcmp(seed_text, "random") != 0) {
1257 const char *endptr = seed_text;
1258 unsigned long seed;
1259 errno = 0;
1260 seed = strtoul(seed_text, (char **)&endptr, 10);
1261 if (*endptr != '\0'
1262 || seed > 4294967295UL
1263 || (errno == ERANGE && seed == ULONG_MAX))
1264 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001265 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001266 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001267 }
1268 /* Use a specific hash */
1269 config->use_hash_seed = 1;
1270 config->hash_seed = seed;
1271 }
1272 else {
1273 /* Use a random hash */
1274 config->use_hash_seed = 0;
1275 config->hash_seed = 0;
1276 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001277 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001278}
1279
1280
Victor Stinner6c785c02018-08-01 17:56:14 +02001281static int
1282config_wstr_to_int(const wchar_t *wstr, int *result)
1283{
1284 const wchar_t *endptr = wstr;
1285 errno = 0;
1286 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1287 if (*endptr != '\0' || errno == ERANGE) {
1288 return -1;
1289 }
1290 if (value < INT_MIN || value > INT_MAX) {
1291 return -1;
1292 }
1293
1294 *result = (int)value;
1295 return 0;
1296}
1297
1298
Victor Stinner331a6a52019-05-27 16:39:22 +02001299static PyStatus
1300config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001301{
Victor Stinner331a6a52019-05-27 16:39:22 +02001302 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001303 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001304
Victor Stinner6c785c02018-08-01 17:56:14 +02001305 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001306 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1307 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1308 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1309 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001310
1311 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001312 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001313 if (dont_write_bytecode) {
1314 config->write_bytecode = 0;
1315 }
1316
1317 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001318 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001319 if (no_user_site_directory) {
1320 config->user_site_directory = 0;
1321 }
1322
1323 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001324 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001325 if (unbuffered_stdio) {
1326 config->buffered_stdio = 0;
1327 }
1328
1329#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001330 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001331 "PYTHONLEGACYWINDOWSSTDIO");
1332#endif
1333
Victor Stinner331a6a52019-05-27 16:39:22 +02001334 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001335 config->dump_refs = 1;
1336 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001337 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001338 config->malloc_stats = 1;
1339 }
1340
Victor Stinner331a6a52019-05-27 16:39:22 +02001341 if (config->pythonpath_env == NULL) {
1342 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1343 L"PYTHONPATH", "PYTHONPATH");
1344 if (_PyStatus_EXCEPTION(status)) {
1345 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001346 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001347 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001348
Victor Stinner81750642020-06-08 19:36:13 +02001349 if(config->platlibdir == NULL) {
1350 status = CONFIG_GET_ENV_DUP(config, &config->platlibdir,
1351 L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR");
1352 if (_PyStatus_EXCEPTION(status)) {
1353 return status;
1354 }
1355 }
1356
Victor Stinner6c785c02018-08-01 17:56:14 +02001357 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001358 status = config_init_hash_seed(config);
1359 if (_PyStatus_EXCEPTION(status)) {
1360 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001361 }
1362 }
1363
Victor Stinner331a6a52019-05-27 16:39:22 +02001364 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001365}
1366
1367
Victor Stinner331a6a52019-05-27 16:39:22 +02001368static PyStatus
1369config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001370{
1371 int nframe;
1372 int valid;
1373
Victor Stinner331a6a52019-05-27 16:39:22 +02001374 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001375 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001376 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001377 valid = (nframe >= 0);
1378 }
1379 else {
1380 valid = 0;
1381 }
1382 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001383 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001384 }
1385 config->tracemalloc = nframe;
1386 }
1387
1388 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1389 if (xoption) {
1390 const wchar_t *sep = wcschr(xoption, L'=');
1391 if (sep) {
1392 if (!config_wstr_to_int(sep + 1, &nframe)) {
1393 valid = (nframe >= 0);
1394 }
1395 else {
1396 valid = 0;
1397 }
1398 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001399 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1400 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001401 }
1402 }
1403 else {
1404 /* -X tracemalloc behaves as -X tracemalloc=1 */
1405 nframe = 1;
1406 }
1407 config->tracemalloc = nframe;
1408 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001409 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001410}
1411
1412
Victor Stinner331a6a52019-05-27 16:39:22 +02001413static PyStatus
1414config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001415{
1416 assert(config->pycache_prefix == NULL);
1417
1418 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1419 if (xoption) {
1420 const wchar_t *sep = wcschr(xoption, L'=');
1421 if (sep && wcslen(sep) > 1) {
1422 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1423 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001424 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001425 }
1426 }
1427 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001428 // PYTHONPYCACHEPREFIX env var ignored
1429 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001430 config->pycache_prefix = NULL;
1431 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001432 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001433 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001434
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001435 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1436 L"PYTHONPYCACHEPREFIX",
1437 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001438}
1439
1440
Victor Stinner331a6a52019-05-27 16:39:22 +02001441static PyStatus
1442config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001443{
1444 /* More complex options configured by env var and -X option */
1445 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001446 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001447 || config_get_xoption(config, L"faulthandler")) {
1448 config->faulthandler = 1;
1449 }
1450 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001451 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001452 || config_get_xoption(config, L"importtime")) {
1453 config->import_time = 1;
1454 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001455
Pablo Galindoc5fc1562020-04-22 23:29:27 +01001456 if (config_get_env(config, "PYTHONOLDPARSER")
1457 || config_get_xoption(config, L"oldparser")) {
Victor Stinner1def7752020-04-23 03:03:24 +02001458 config->_use_peg_parser = 0;
Pablo Galindoc5fc1562020-04-22 23:29:27 +01001459 }
1460
Victor Stinner331a6a52019-05-27 16:39:22 +02001461 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001462 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001463 status = config_init_tracemalloc(config);
1464 if (_PyStatus_EXCEPTION(status)) {
1465 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001466 }
1467 }
1468
1469 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001470 status = config_init_pycache_prefix(config);
1471 if (_PyStatus_EXCEPTION(status)) {
1472 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001473 }
1474 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001475 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001476}
1477
1478
Victor Stinner709d23d2019-05-02 14:56:30 -04001479static const wchar_t *
Andy Lesteraa450a02020-03-07 11:36:04 -06001480config_get_stdio_errors(void)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001481{
1482#ifndef MS_WINDOWS
1483 const char *loc = setlocale(LC_CTYPE, NULL);
1484 if (loc != NULL) {
1485 /* surrogateescape is the default in the legacy C and POSIX locales */
1486 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001487 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001488 }
1489
1490#ifdef PY_COERCE_C_LOCALE
1491 /* surrogateescape is the default in locale coercion target locales */
1492 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001493 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001494 }
1495#endif
1496 }
1497
Victor Stinner709d23d2019-05-02 14:56:30 -04001498 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001499#else
1500 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001501 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001502#endif
1503}
1504
1505
Victor Stinner331a6a52019-05-27 16:39:22 +02001506static PyStatus
1507config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001508{
1509#ifdef MS_WINDOWS
1510 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001511 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001512 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001513#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001514 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001515#else
1516 const char *encoding = nl_langinfo(CODESET);
1517 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001518 return _PyStatus_ERR("failed to get the locale encoding: "
1519 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001520 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001521 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001522 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001523 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001524 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001525#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001526}
1527
1528
Victor Stinner331a6a52019-05-27 16:39:22 +02001529static PyStatus
1530config_init_stdio_encoding(PyConfig *config,
1531 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001532{
Victor Stinner331a6a52019-05-27 16:39:22 +02001533 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001534
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001535 /* If Py_SetStandardStreamEncoding() have been called, use these
1536 parameters. */
1537 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001538 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1539 _Py_StandardStreamEncoding,
1540 "_Py_StandardStreamEncoding");
1541 if (_PyStatus_EXCEPTION(status)) {
1542 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001543 }
1544 }
1545
1546 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001547 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1548 _Py_StandardStreamErrors,
1549 "_Py_StandardStreamErrors");
1550 if (_PyStatus_EXCEPTION(status)) {
1551 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001552 }
1553 }
1554
1555 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001556 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001557 }
1558
1559 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001560 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001561 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001562 char *pythonioencoding = _PyMem_RawStrdup(opt);
1563 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001564 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001565 }
1566
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001567 char *errors = strchr(pythonioencoding, ':');
1568 if (errors) {
1569 *errors = '\0';
1570 errors++;
1571 if (!errors[0]) {
1572 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001573 }
1574 }
1575
1576 /* Does PYTHONIOENCODING contain an encoding? */
1577 if (pythonioencoding[0]) {
1578 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001579 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1580 pythonioencoding,
1581 "PYTHONIOENCODING environment variable");
1582 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001583 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001584 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001585 }
1586 }
1587
1588 /* If the encoding is set but not the error handler,
1589 use "strict" error handler by default.
1590 PYTHONIOENCODING=latin1 behaves as
1591 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001592 if (!errors) {
1593 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001594 }
1595 }
1596
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001597 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001598 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1599 errors,
1600 "PYTHONIOENCODING environment variable");
1601 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001602 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001603 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001604 }
1605 }
1606
1607 PyMem_RawFree(pythonioencoding);
1608 }
1609
1610 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001611 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001612 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001613 status = PyConfig_SetString(config, &config->stdio_encoding,
1614 L"utf-8");
1615 if (_PyStatus_EXCEPTION(status)) {
1616 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001617 }
1618 }
1619 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001620 status = PyConfig_SetString(config, &config->stdio_errors,
1621 L"surrogateescape");
1622 if (_PyStatus_EXCEPTION(status)) {
1623 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001624 }
1625 }
1626 }
1627
1628 /* Choose the default error handler based on the current locale. */
1629 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001630 status = config_get_locale_encoding(config, &config->stdio_encoding);
1631 if (_PyStatus_EXCEPTION(status)) {
1632 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001633 }
1634 }
1635 if (config->stdio_errors == NULL) {
Andy Lesteraa450a02020-03-07 11:36:04 -06001636 const wchar_t *errors = config_get_stdio_errors();
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001637 assert(errors != NULL);
1638
Victor Stinner331a6a52019-05-27 16:39:22 +02001639 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1640 if (_PyStatus_EXCEPTION(status)) {
1641 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001642 }
1643 }
1644
Victor Stinner331a6a52019-05-27 16:39:22 +02001645 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001646}
1647
1648
Victor Stinner331a6a52019-05-27 16:39:22 +02001649static PyStatus
1650config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001651{
Victor Stinner331a6a52019-05-27 16:39:22 +02001652 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001653
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001654 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001655#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001656 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001657#else
Victor Stinnere2510952019-05-02 11:28:57 -04001658
1659#ifdef MS_WINDOWS
1660 if (preconfig->legacy_windows_fs_encoding) {
1661 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001662 status = PyConfig_SetString(config, &config->filesystem_encoding,
1663 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001664 }
1665 else
1666#endif
Victor Stinner20004952019-03-26 02:31:11 +01001667 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001668 status = PyConfig_SetString(config, &config->filesystem_encoding,
1669 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001670 }
Victor Stinnere2510952019-05-02 11:28:57 -04001671#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001672 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001673 status = PyConfig_SetString(config, &config->filesystem_encoding,
1674 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001675 }
Victor Stinnere2510952019-05-02 11:28:57 -04001676#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001677 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001678#ifdef MS_WINDOWS
1679 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001680 status = PyConfig_SetString(config, &config->filesystem_encoding,
1681 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001682#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001683 status = config_get_locale_encoding(config,
1684 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001685#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001686 }
Victor Stinnere2510952019-05-02 11:28:57 -04001687#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001688
Victor Stinner331a6a52019-05-27 16:39:22 +02001689 if (_PyStatus_EXCEPTION(status)) {
1690 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001691 }
1692 }
1693
1694 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001695 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001696#ifdef MS_WINDOWS
1697 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001698 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001699 }
1700 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001701 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001702 }
1703#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001704 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001705#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001706 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1707 if (_PyStatus_EXCEPTION(status)) {
1708 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001709 }
1710 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001711 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001712}
1713
1714
Victor Stinner331a6a52019-05-27 16:39:22 +02001715static PyStatus
1716config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001717{
Victor Stinner331a6a52019-05-27 16:39:22 +02001718 PyStatus status;
1719 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001720
Victor Stinner20004952019-03-26 02:31:11 +01001721 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001722 status = config_read_env_vars(config);
1723 if (_PyStatus_EXCEPTION(status)) {
1724 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001725 }
1726 }
1727
1728 /* -X options */
1729 if (config_get_xoption(config, L"showrefcount")) {
1730 config->show_ref_count = 1;
1731 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001732
Victor Stinner331a6a52019-05-27 16:39:22 +02001733 status = config_read_complex_options(config);
1734 if (_PyStatus_EXCEPTION(status)) {
1735 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001736 }
1737
Victor Stinner6c785c02018-08-01 17:56:14 +02001738 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001739 status = config_init_home(config);
1740 if (_PyStatus_EXCEPTION(status)) {
1741 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001742 }
1743 }
1744
Steve Dower177a41a2018-11-17 20:41:48 -08001745 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001746 status = config_init_executable(config);
1747 if (_PyStatus_EXCEPTION(status)) {
1748 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001749 }
1750 }
1751
Victor Stinner81750642020-06-08 19:36:13 +02001752 if(config->platlibdir == NULL) {
1753 status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR,
1754 "PLATLIBDIR macro");
1755 if (_PyStatus_EXCEPTION(status)) {
1756 return status;
1757 }
1758 }
1759
Victor Stinner6c785c02018-08-01 17:56:14 +02001760 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001761 status = _PyConfig_InitPathConfig(config);
1762 if (_PyStatus_EXCEPTION(status)) {
1763 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001764 }
1765 }
1766
1767 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001768 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001769 if (config->faulthandler < 0) {
1770 config->faulthandler = 1;
1771 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001772 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001773 if (config->faulthandler < 0) {
1774 config->faulthandler = 0;
1775 }
1776 if (config->tracemalloc < 0) {
1777 config->tracemalloc = 0;
1778 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001779 if (config->use_hash_seed < 0) {
1780 config->use_hash_seed = 0;
1781 config->hash_seed = 0;
1782 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001783
Victor Stinner70fead22018-08-29 13:45:34 +02001784 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001785 status = config_init_fs_encoding(config, preconfig);
1786 if (_PyStatus_EXCEPTION(status)) {
1787 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001788 }
1789 }
1790
Victor Stinner331a6a52019-05-27 16:39:22 +02001791 status = config_init_stdio_encoding(config, preconfig);
1792 if (_PyStatus_EXCEPTION(status)) {
1793 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001794 }
1795
Victor Stinner62599762019-03-15 16:03:23 +01001796 if (config->argv.length < 1) {
1797 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001798 status = PyWideStringList_Append(&config->argv, L"");
1799 if (_PyStatus_EXCEPTION(status)) {
1800 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001801 }
1802 }
Victor Stinner870b0352019-05-17 03:15:12 +02001803
1804 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001805 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1806 L"default");
1807 if (_PyStatus_EXCEPTION(status)) {
1808 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001809 }
1810 }
1811
1812 if (config->configure_c_stdio < 0) {
1813 config->configure_c_stdio = 1;
1814 }
1815
Victor Stinner331a6a52019-05-27 16:39:22 +02001816 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001817}
Victor Stinner5ed69952018-11-06 15:59:52 +01001818
1819
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001820static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001821config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001822{
1823#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1824 /* don't translate newlines (\r\n <=> \n) */
1825 _setmode(fileno(stdin), O_BINARY);
1826 _setmode(fileno(stdout), O_BINARY);
1827 _setmode(fileno(stderr), O_BINARY);
1828#endif
1829
1830 if (!config->buffered_stdio) {
1831#ifdef HAVE_SETVBUF
1832 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1833 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1834 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1835#else /* !HAVE_SETVBUF */
1836 setbuf(stdin, (char *)NULL);
1837 setbuf(stdout, (char *)NULL);
1838 setbuf(stderr, (char *)NULL);
1839#endif /* !HAVE_SETVBUF */
1840 }
1841 else if (config->interactive) {
1842#ifdef MS_WINDOWS
1843 /* Doesn't have to have line-buffered -- use unbuffered */
1844 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1845 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1846#else /* !MS_WINDOWS */
1847#ifdef HAVE_SETVBUF
1848 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1849 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1850#endif /* HAVE_SETVBUF */
1851#endif /* !MS_WINDOWS */
1852 /* Leave stderr alone - it should be unbuffered anyway. */
1853 }
1854}
1855
1856
1857/* Write the configuration:
1858
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001859 - set Py_xxx global configuration variables
1860 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinnerdedaac02020-06-08 18:44:50 +02001861PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +02001862_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001863{
Victor Stinner331a6a52019-05-27 16:39:22 +02001864 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001865
1866 if (config->configure_c_stdio) {
1867 config_init_stdio(config);
1868 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001869
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001870 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001871 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001872 preconfig->isolated = config->isolated;
1873 preconfig->use_environment = config->use_environment;
1874 preconfig->dev_mode = config->dev_mode;
Victor Stinnerdedaac02020-06-08 18:44:50 +02001875
1876 if (_Py_SetArgcArgv(config->_orig_argv.length,
1877 config->_orig_argv.items) < 0)
1878 {
1879 return _PyStatus_NO_MEMORY();
1880 }
1881 return _PyStatus_OK();
Victor Stinner5ed69952018-11-06 15:59:52 +01001882}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001883
1884
Victor Stinner331a6a52019-05-27 16:39:22 +02001885/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001886
1887static void
Victor Stinner2f549082019-03-29 15:13:46 +01001888config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001889{
Victor Stinner2f549082019-03-29 15:13:46 +01001890 FILE *f = error ? stderr : stdout;
1891
1892 fprintf(f, usage_line, program);
1893 if (error)
1894 fprintf(f, "Try `python -h' for more information.\n");
1895 else {
1896 fputs(usage_1, f);
1897 fputs(usage_2, f);
1898 fputs(usage_3, f);
1899 fprintf(f, usage_4, (wint_t)DELIM);
1900 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1901 fputs(usage_6, f);
1902 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001903}
1904
1905
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001906/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001907static PyStatus
1908config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001909 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001910{
Victor Stinner331a6a52019-05-27 16:39:22 +02001911 PyStatus status;
1912 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001913 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001914 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001915
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001916 _PyOS_ResetGetOpt();
1917 do {
1918 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001919 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001920 if (c == EOF) {
1921 break;
1922 }
1923
1924 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001925 if (config->run_command == NULL) {
1926 /* -c is the last option; following arguments
1927 that look like options are left for the
1928 command to interpret. */
1929 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1930 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1931 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001932 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001933 }
1934 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1935 command[len - 2] = '\n';
1936 command[len - 1] = 0;
1937 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001938 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001939 break;
1940 }
1941
1942 if (c == 'm') {
1943 /* -m is the last option; following arguments
1944 that look like options are left for the
1945 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001946 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001947 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1948 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001949 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001950 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001951 }
1952 break;
1953 }
1954
1955 switch (c) {
1956 case 0:
1957 // Handle long option.
1958 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001959 if (wcscmp(_PyOS_optarg, L"always") == 0
1960 || wcscmp(_PyOS_optarg, L"never") == 0
1961 || wcscmp(_PyOS_optarg, L"default") == 0)
1962 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001963 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1964 _PyOS_optarg);
1965 if (_PyStatus_EXCEPTION(status)) {
1966 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001967 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001968 } else {
1969 fprintf(stderr, "--check-hash-based-pycs must be one of "
1970 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001971 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001972 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001973 }
1974 break;
1975
1976 case 'b':
1977 config->bytes_warning++;
1978 break;
1979
1980 case 'd':
1981 config->parser_debug++;
1982 break;
1983
1984 case 'i':
1985 config->inspect++;
1986 config->interactive++;
1987 break;
1988
Victor Stinner6dcb5422019-03-05 02:44:12 +01001989 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001990 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001991 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001992 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001993 break;
1994
1995 /* case 'J': reserved for Jython */
1996
1997 case 'O':
1998 config->optimization_level++;
1999 break;
2000
2001 case 'B':
2002 config->write_bytecode = 0;
2003 break;
2004
2005 case 's':
2006 config->user_site_directory = 0;
2007 break;
2008
2009 case 'S':
2010 config->site_import = 0;
2011 break;
2012
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002013 case 't':
2014 /* ignored for backwards compatibility */
2015 break;
2016
2017 case 'u':
2018 config->buffered_stdio = 0;
2019 break;
2020
2021 case 'v':
2022 config->verbose++;
2023 break;
2024
2025 case 'x':
2026 config->skip_source_first_line = 1;
2027 break;
2028
2029 case 'h':
2030 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02002031 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002032 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002033
2034 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01002035 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002036 break;
2037
2038 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002039 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2040 if (_PyStatus_EXCEPTION(status)) {
2041 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002042 }
2043 break;
2044
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002045 case 'q':
2046 config->quiet++;
2047 break;
2048
2049 case 'R':
2050 config->use_hash_seed = 0;
2051 break;
2052
2053 /* This space reserved for other options */
2054
2055 default:
2056 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002057 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002058 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002059 }
2060 } while (1);
2061
Victor Stinner2f549082019-03-29 15:13:46 +01002062 if (print_version) {
2063 printf("Python %s\n",
2064 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002065 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002066 }
2067
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002068 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002069 && _PyOS_optind < argv->length
2070 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002071 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002072 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002073 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002074 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002075 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002076 }
2077 }
2078
2079 if (config->run_command != NULL || config->run_module != NULL) {
2080 /* Backup _PyOS_optind */
2081 _PyOS_optind--;
2082 }
2083
Victor Stinnerae239f62019-05-16 17:02:56 +02002084 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002085
Victor Stinner331a6a52019-05-27 16:39:22 +02002086 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002087}
2088
2089
2090#ifdef MS_WINDOWS
2091# define WCSTOK wcstok_s
2092#else
2093# define WCSTOK wcstok
2094#endif
2095
2096/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002097static PyStatus
2098config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002099{
Victor Stinner331a6a52019-05-27 16:39:22 +02002100 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002101 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2102 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002103 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002104 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002105 if (_PyStatus_EXCEPTION(status)) {
2106 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002107 }
2108
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002109 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002110 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002111 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002112 }
2113
2114
2115 wchar_t *warning, *context = NULL;
2116 for (warning = WCSTOK(env, L",", &context);
2117 warning != NULL;
2118 warning = WCSTOK(NULL, L",", &context))
2119 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002120 status = PyWideStringList_Append(warnoptions, warning);
2121 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002122 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002123 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002124 }
2125 }
2126 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002127 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002128}
2129
2130
Victor Stinner331a6a52019-05-27 16:39:22 +02002131static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002132warnoptions_append(PyConfig *config, PyWideStringList *options,
2133 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002134{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002135 /* config_init_warnoptions() add existing config warnoptions at the end:
2136 ensure that the new option is not already present in this list to
2137 prevent change the options order whne config_init_warnoptions() is
2138 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002139 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002140 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002141 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002142 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002143 if (_PyWideStringList_Find(options, option)) {
2144 /* Already present: do nothing */
2145 return _PyStatus_OK();
2146 }
2147 return PyWideStringList_Append(options, option);
2148}
2149
2150
2151static PyStatus
2152warnoptions_extend(PyConfig *config, PyWideStringList *options,
2153 const PyWideStringList *options2)
2154{
2155 const Py_ssize_t len = options2->length;
2156 wchar_t *const *items = options2->items;
2157
2158 for (Py_ssize_t i = 0; i < len; i++) {
2159 PyStatus status = warnoptions_append(config, options, items[i]);
2160 if (_PyStatus_EXCEPTION(status)) {
2161 return status;
2162 }
2163 }
2164 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002165}
2166
2167
Victor Stinner331a6a52019-05-27 16:39:22 +02002168static PyStatus
2169config_init_warnoptions(PyConfig *config,
2170 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002171 const PyWideStringList *env_warnoptions,
2172 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002173{
Victor Stinner331a6a52019-05-27 16:39:22 +02002174 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002175 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002176
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002177 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002178 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002179 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002180 * - PyConfig.dev_mode: "default" filter
2181 * - PYTHONWARNINGS environment variable
2182 * - '-W' command line options
2183 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2184 * "default::BytesWarning" or "error::BytesWarning" filter
2185 * - early PySys_AddWarnOption() calls
2186 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002187 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002188 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2189 * module works on the basis of "the most recently added filter will be
2190 * checked first", we add the lowest precedence entries first so that later
2191 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002192 */
2193
Victor Stinner20004952019-03-26 02:31:11 +01002194 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002195 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002196 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002197 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002198 }
2199 }
2200
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002201 status = warnoptions_extend(config, &options, env_warnoptions);
2202 if (_PyStatus_EXCEPTION(status)) {
2203 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002204 }
2205
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002206 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2207 if (_PyStatus_EXCEPTION(status)) {
2208 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002209 }
2210
2211 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2212 * don't even try to emit a warning, so we skip setting the filter in that
2213 * case.
2214 */
2215 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002216 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002217 if (config->bytes_warning> 1) {
2218 filter = L"error::BytesWarning";
2219 }
2220 else {
2221 filter = L"default::BytesWarning";
2222 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002223 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002224 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002225 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002226 }
2227 }
Victor Stinner120b7072019-08-23 18:03:08 +01002228
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002229 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002230 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002231 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002232 }
2233
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002234 /* Always add all PyConfig.warnoptions options */
2235 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2236 if (_PyStatus_EXCEPTION(status)) {
2237 goto error;
2238 }
2239
2240 _PyWideStringList_Clear(&config->warnoptions);
2241 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002242 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002243
2244error:
2245 _PyWideStringList_Clear(&options);
2246 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002247}
2248
2249
Victor Stinner331a6a52019-05-27 16:39:22 +02002250static PyStatus
2251config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002252{
Victor Stinner331a6a52019-05-27 16:39:22 +02002253 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002254 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002255
Victor Stinner74f65682019-03-15 15:08:05 +01002256 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002257 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002258 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002259 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2260 if (_PyStatus_EXCEPTION(status)) {
2261 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002262 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002263 }
2264 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002265 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002266 slice.length = cmdline_argv->length - opt_index;
2267 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002268 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2269 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002270 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002271 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002272 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002273
2274 wchar_t *arg0 = NULL;
2275 if (config->run_command != NULL) {
2276 /* Force sys.argv[0] = '-c' */
2277 arg0 = L"-c";
2278 }
2279 else if (config->run_module != NULL) {
2280 /* Force sys.argv[0] = '-m'*/
2281 arg0 = L"-m";
2282 }
Victor Stinner3939c322019-06-25 15:02:43 +02002283
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002284 if (arg0 != NULL) {
2285 arg0 = _PyMem_RawWcsdup(arg0);
2286 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002287 _PyWideStringList_Clear(&config_argv);
2288 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002289 }
2290
Victor Stinnerfa153762019-03-20 04:25:38 +01002291 PyMem_RawFree(config_argv.items[0]);
2292 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002293 }
2294
Victor Stinner331a6a52019-05-27 16:39:22 +02002295 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002296 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002297 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002298}
2299
2300
Victor Stinner331a6a52019-05-27 16:39:22 +02002301static PyStatus
2302core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002303{
Victor Stinner331a6a52019-05-27 16:39:22 +02002304 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002305
Victor Stinnercab5d072019-05-17 19:01:14 +02002306 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002307 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2308 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002309 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002310 }
2311
Victor Stinner331a6a52019-05-27 16:39:22 +02002312 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002313
2314 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2315 if (_PyStatus_EXCEPTION(status)) {
2316 return status;
2317 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002318
Victor Stinner331a6a52019-05-27 16:39:22 +02002319 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002320
Victor Stinner331a6a52019-05-27 16:39:22 +02002321 status = _PyPreCmdline_Read(precmdline, &preconfig);
2322 if (_PyStatus_EXCEPTION(status)) {
2323 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002324 }
2325
Victor Stinner331a6a52019-05-27 16:39:22 +02002326 status = _PyPreCmdline_SetConfig(precmdline, config);
2327 if (_PyStatus_EXCEPTION(status)) {
2328 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002329 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002330 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002331}
2332
2333
Victor Stinner3939c322019-06-25 15:02:43 +02002334/* Get run_filename absolute path */
2335static PyStatus
2336config_run_filename_abspath(PyConfig *config)
2337{
2338 if (!config->run_filename) {
2339 return _PyStatus_OK();
2340 }
2341
2342#ifndef MS_WINDOWS
2343 if (_Py_isabs(config->run_filename)) {
2344 /* path is already absolute */
2345 return _PyStatus_OK();
2346 }
2347#endif
2348
2349 wchar_t *abs_filename;
2350 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2351 /* failed to get the absolute path of the command line filename:
2352 ignore the error, keep the relative path */
2353 return _PyStatus_OK();
2354 }
2355 if (abs_filename == NULL) {
2356 return _PyStatus_NO_MEMORY();
2357 }
2358
2359 PyMem_RawFree(config->run_filename);
2360 config->run_filename = abs_filename;
2361 return _PyStatus_OK();
2362}
2363
2364
Victor Stinner331a6a52019-05-27 16:39:22 +02002365static PyStatus
2366config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002367{
Victor Stinner331a6a52019-05-27 16:39:22 +02002368 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002369 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2370 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2371 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002372
Victor Stinnerae239f62019-05-16 17:02:56 +02002373 if (config->parse_argv < 0) {
2374 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002375 }
Victor Stinner870b0352019-05-17 03:15:12 +02002376
Victor Stinnerfed02e12019-05-17 11:12:09 +02002377 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002378 status = config_init_program_name(config);
2379 if (_PyStatus_EXCEPTION(status)) {
2380 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002381 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002382 }
Victor Stinner2f549082019-03-29 15:13:46 +01002383
Victor Stinnerae239f62019-05-16 17:02:56 +02002384 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002385 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002386 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2387 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002388 goto done;
2389 }
2390
Victor Stinner3939c322019-06-25 15:02:43 +02002391 status = config_run_filename_abspath(config);
2392 if (_PyStatus_EXCEPTION(status)) {
2393 goto done;
2394 }
2395
Victor Stinner331a6a52019-05-27 16:39:22 +02002396 status = config_update_argv(config, opt_index);
2397 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002398 goto done;
2399 }
Victor Stinner2f549082019-03-29 15:13:46 +01002400 }
Victor Stinner3939c322019-06-25 15:02:43 +02002401 else {
2402 status = config_run_filename_abspath(config);
2403 if (_PyStatus_EXCEPTION(status)) {
2404 goto done;
2405 }
2406 }
Victor Stinner2f549082019-03-29 15:13:46 +01002407
Victor Stinner2f549082019-03-29 15:13:46 +01002408 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002409 status = config_init_env_warnoptions(config, &env_warnoptions);
2410 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002411 goto done;
2412 }
2413 }
2414
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002415 /* Handle early PySys_AddWarnOption() calls */
2416 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2417 if (_PyStatus_EXCEPTION(status)) {
2418 goto done;
2419 }
2420
Victor Stinner331a6a52019-05-27 16:39:22 +02002421 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002422 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002423 &env_warnoptions,
2424 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002425 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002426 goto done;
2427 }
2428
Victor Stinner331a6a52019-05-27 16:39:22 +02002429 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002430
2431done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002432 _PyWideStringList_Clear(&cmdline_warnoptions);
2433 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002434 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002435 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002436}
2437
2438
Victor Stinner331a6a52019-05-27 16:39:22 +02002439PyStatus
2440_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002441{
Victor Stinner331a6a52019-05-27 16:39:22 +02002442 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2443 if (_PyStatus_EXCEPTION(status)) {
2444 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002445 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002446
Victor Stinner5f38b842019-05-01 02:30:12 +02002447 return _PyArgv_AsWstrList(args, &config->argv);
2448}
2449
2450
Victor Stinner70005ac2019-05-02 15:25:34 -04002451/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2452 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002453PyStatus
2454PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002455{
2456 _PyArgv args = {
2457 .argc = argc,
2458 .use_bytes_argv = 1,
2459 .bytes_argv = argv,
2460 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002461 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002462}
2463
2464
Victor Stinner331a6a52019-05-27 16:39:22 +02002465PyStatus
2466PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002467{
2468 _PyArgv args = {
2469 .argc = argc,
2470 .use_bytes_argv = 0,
2471 .bytes_argv = NULL,
2472 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002473 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002474}
2475
2476
Victor Stinner36242fd2019-07-01 19:13:50 +02002477PyStatus
2478PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2479 Py_ssize_t length, wchar_t **items)
2480{
2481 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2482 if (_PyStatus_EXCEPTION(status)) {
2483 return status;
2484 }
2485
2486 PyWideStringList list2 = {.length = length, .items = items};
2487 if (_PyWideStringList_Copy(list, &list2) < 0) {
2488 return _PyStatus_NO_MEMORY();
2489 }
2490 return _PyStatus_OK();
2491}
2492
2493
Victor Stinner331a6a52019-05-27 16:39:22 +02002494/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002495
2496 * Command line arguments
2497 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002498 * Py_xxx global configuration variables
2499
2500 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002501PyStatus
2502PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002503{
Victor Stinner331a6a52019-05-27 16:39:22 +02002504 PyStatus status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002505
Victor Stinner331a6a52019-05-27 16:39:22 +02002506 status = _Py_PreInitializeFromConfig(config, NULL);
2507 if (_PyStatus_EXCEPTION(status)) {
2508 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002509 }
2510
Victor Stinner331a6a52019-05-27 16:39:22 +02002511 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002512
Victor Stinnerdedaac02020-06-08 18:44:50 +02002513 if (config->_orig_argv.length == 0
2514 && !(config->argv.length == 1
2515 && wcscmp(config->argv.items[0], L"") == 0))
2516 {
2517 if (_PyWideStringList_Copy(&config->_orig_argv, &config->argv) < 0) {
2518 return _PyStatus_NO_MEMORY();
2519 }
Victor Stinnercab5d072019-05-17 19:01:14 +02002520 }
2521
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002522 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002523 status = core_read_precmdline(config, &precmdline);
2524 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002525 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002526 }
2527
Victor Stinner870b0352019-05-17 03:15:12 +02002528 assert(config->isolated >= 0);
2529 if (config->isolated) {
2530 config->use_environment = 0;
2531 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002532 }
2533
Victor Stinner331a6a52019-05-27 16:39:22 +02002534 status = config_read_cmdline(config);
2535 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002536 goto done;
2537 }
2538
Victor Stinner120b7072019-08-23 18:03:08 +01002539 /* Handle early PySys_AddXOption() calls */
2540 status = _PySys_ReadPreinitXOptions(config);
2541 if (_PyStatus_EXCEPTION(status)) {
2542 goto done;
2543 }
2544
Victor Stinner331a6a52019-05-27 16:39:22 +02002545 status = config_read(config);
2546 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002547 goto done;
2548 }
2549
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002550 /* Check config consistency */
2551 assert(config->isolated >= 0);
2552 assert(config->use_environment >= 0);
2553 assert(config->dev_mode >= 0);
Victor Stinner1def7752020-04-23 03:03:24 +02002554 assert(config->_use_peg_parser >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002555 assert(config->install_signal_handlers >= 0);
2556 assert(config->use_hash_seed >= 0);
2557 assert(config->faulthandler >= 0);
2558 assert(config->tracemalloc >= 0);
2559 assert(config->site_import >= 0);
2560 assert(config->bytes_warning >= 0);
2561 assert(config->inspect >= 0);
2562 assert(config->interactive >= 0);
2563 assert(config->optimization_level >= 0);
2564 assert(config->parser_debug >= 0);
2565 assert(config->write_bytecode >= 0);
2566 assert(config->verbose >= 0);
2567 assert(config->quiet >= 0);
2568 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002569 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002570 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002571 assert(config->buffered_stdio >= 0);
2572 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002573 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002574 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2575 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002576 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2577 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2578 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002579 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002580 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002581 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002582 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002583 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002584 assert(config->prefix != NULL);
2585 assert(config->base_prefix != NULL);
2586 assert(config->exec_prefix != NULL);
2587 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002588 }
Victor Stinner81750642020-06-08 19:36:13 +02002589 assert(config->platlibdir != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002590 assert(config->filesystem_encoding != NULL);
2591 assert(config->filesystem_errors != NULL);
2592 assert(config->stdio_encoding != NULL);
2593 assert(config->stdio_errors != NULL);
2594#ifdef MS_WINDOWS
2595 assert(config->legacy_windows_stdio >= 0);
2596#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002597 /* -c and -m options are exclusive */
2598 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002599 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002600 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002601 assert(config->pathconfig_warnings >= 0);
Victor Stinnerdedaac02020-06-08 18:44:50 +02002602 assert(_PyWideStringList_CheckConsistency(&config->_orig_argv));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002603
Victor Stinner331a6a52019-05-27 16:39:22 +02002604 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002605
2606done:
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002607 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002608 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002609}
Victor Stinner1075d162019-03-25 23:19:57 +01002610
2611
2612PyObject*
2613_Py_GetConfigsAsDict(void)
2614{
Victor Stinner331a6a52019-05-27 16:39:22 +02002615 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002616 PyObject *dict = NULL;
2617
Victor Stinner331a6a52019-05-27 16:39:22 +02002618 result = PyDict_New();
2619 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002620 goto error;
2621 }
2622
Victor Stinner331a6a52019-05-27 16:39:22 +02002623 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002624 dict = _Py_GetGlobalVariablesAsDict();
2625 if (dict == NULL) {
2626 goto error;
2627 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002628 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002629 goto error;
2630 }
2631 Py_CLEAR(dict);
2632
2633 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002634 PyThreadState *tstate = _PyThreadState_GET();
2635 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002636 dict = _PyPreConfig_AsDict(pre_config);
2637 if (dict == NULL) {
2638 goto error;
2639 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002640 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002641 goto error;
2642 }
2643 Py_CLEAR(dict);
2644
2645 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002646 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinner331a6a52019-05-27 16:39:22 +02002647 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002648 if (dict == NULL) {
2649 goto error;
2650 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002651 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002652 goto error;
2653 }
2654 Py_CLEAR(dict);
2655
Victor Stinner331a6a52019-05-27 16:39:22 +02002656 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002657
2658error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002659 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002660 Py_XDECREF(dict);
2661 return NULL;
2662}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002663
2664
2665static void
2666init_dump_ascii_wstr(const wchar_t *str)
2667{
2668 if (str == NULL) {
2669 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002670 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002671 }
2672
2673 PySys_WriteStderr("'");
2674 for (; *str != L'\0'; str++) {
2675 wchar_t ch = *str;
2676 if (ch == L'\'') {
2677 PySys_WriteStderr("\\'");
2678 } else if (0x20 <= ch && ch < 0x7f) {
2679 PySys_WriteStderr("%lc", ch);
2680 }
2681 else if (ch <= 0xff) {
2682 PySys_WriteStderr("\\x%02x", ch);
2683 }
2684#if SIZEOF_WCHAR_T > 2
2685 else if (ch > 0xffff) {
2686 PySys_WriteStderr("\\U%08x", ch);
2687 }
2688#endif
2689 else {
2690 PySys_WriteStderr("\\u%04x", ch);
2691 }
2692 }
2693 PySys_WriteStderr("'");
2694}
2695
2696
2697/* Dump the Python path configuration into sys.stderr */
2698void
2699_Py_DumpPathConfig(PyThreadState *tstate)
2700{
2701 PyObject *exc_type, *exc_value, *exc_tb;
2702 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2703
2704 PySys_WriteStderr("Python path configuration:\n");
2705
2706#define DUMP_CONFIG(NAME, FIELD) \
2707 do { \
2708 PySys_WriteStderr(" " NAME " = "); \
2709 init_dump_ascii_wstr(config->FIELD); \
2710 PySys_WriteStderr("\n"); \
2711 } while (0)
2712
Victor Stinnerda7933e2020-04-13 03:04:28 +02002713 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002714 DUMP_CONFIG("PYTHONHOME", home);
2715 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2716 DUMP_CONFIG("program name", program_name);
2717 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2718 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2719 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2720 PySys_WriteStderr(" import site = %i\n", config->site_import);
2721#undef DUMP_CONFIG
2722
2723#define DUMP_SYS(NAME) \
2724 do { \
2725 obj = PySys_GetObject(#NAME); \
2726 PySys_FormatStderr(" sys.%s = ", #NAME); \
2727 if (obj != NULL) { \
2728 PySys_FormatStderr("%A", obj); \
2729 } \
2730 else { \
2731 PySys_WriteStderr("(not set)"); \
2732 } \
2733 PySys_FormatStderr("\n"); \
2734 } while (0)
2735
2736 PyObject *obj;
2737 DUMP_SYS(_base_executable);
2738 DUMP_SYS(base_prefix);
2739 DUMP_SYS(base_exec_prefix);
Victor Stinner81750642020-06-08 19:36:13 +02002740 DUMP_SYS(platlibdir);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002741 DUMP_SYS(executable);
2742 DUMP_SYS(prefix);
2743 DUMP_SYS(exec_prefix);
2744#undef DUMP_SYS
2745
2746 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2747 if (sys_path != NULL && PyList_Check(sys_path)) {
2748 PySys_WriteStderr(" sys.path = [\n");
2749 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2750 for (Py_ssize_t i=0; i < len; i++) {
2751 PyObject *path = PyList_GET_ITEM(sys_path, i);
2752 PySys_FormatStderr(" %A,\n", path);
2753 }
2754 PySys_WriteStderr(" ]\n");
2755 }
2756
2757 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2758}