blob: 998ceb7bbfa5107af5f922b25ff1891302785ef8 [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);
Victor Stinner6c785c02018-08-01 17:56:14 +0200604#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200605}
606
607
Victor Stinner8462a492019-10-01 12:06:16 +0200608void
Victor Stinner331a6a52019-05-27 16:39:22 +0200609_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200610{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200611 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200612
Victor Stinner022be022019-05-22 23:58:50 +0200613 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200614 config->isolated = -1;
615 config->use_environment = -1;
616 config->dev_mode = -1;
617 config->install_signal_handlers = 1;
618 config->use_hash_seed = -1;
619 config->faulthandler = -1;
620 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200621 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200622 config->parse_argv = 0;
623 config->site_import = -1;
624 config->bytes_warning = -1;
625 config->inspect = -1;
626 config->interactive = -1;
627 config->optimization_level = -1;
628 config->parser_debug= -1;
629 config->write_bytecode = -1;
630 config->verbose = -1;
631 config->quiet = -1;
632 config->user_site_directory = -1;
633 config->configure_c_stdio = 0;
634 config->buffered_stdio = -1;
635 config->_install_importlib = 1;
636 config->check_hash_pycs_mode = NULL;
637 config->pathconfig_warnings = -1;
638 config->_init_main = 1;
Victor Stinner252346a2020-05-01 11:33:44 +0200639 config->_isolated_interpreter = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200640#ifdef MS_WINDOWS
641 config->legacy_windows_stdio = -1;
642#endif
Victor Stinner1def7752020-04-23 03:03:24 +0200643 config->_use_peg_parser = 1;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200644}
645
646
Victor Stinner8462a492019-10-01 12:06:16 +0200647static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200648config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200649{
Victor Stinner8462a492019-10-01 12:06:16 +0200650 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200651
652 config->isolated = 0;
653 config->use_environment = 1;
654 config->site_import = 1;
655 config->bytes_warning = 0;
656 config->inspect = 0;
657 config->interactive = 0;
658 config->optimization_level = 0;
659 config->parser_debug= 0;
660 config->write_bytecode = 1;
661 config->verbose = 0;
662 config->quiet = 0;
663 config->user_site_directory = 1;
664 config->buffered_stdio = 1;
665 config->pathconfig_warnings = 1;
666#ifdef MS_WINDOWS
667 config->legacy_windows_stdio = 0;
668#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200669}
670
671
Victor Stinner8462a492019-10-01 12:06:16 +0200672void
Victor Stinner331a6a52019-05-27 16:39:22 +0200673PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200674{
Victor Stinner8462a492019-10-01 12:06:16 +0200675 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200676
Victor Stinner022be022019-05-22 23:58:50 +0200677 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200678 config->configure_c_stdio = 1;
679 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200680}
681
682
Victor Stinner8462a492019-10-01 12:06:16 +0200683void
Victor Stinner331a6a52019-05-27 16:39:22 +0200684PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200685{
Victor Stinner8462a492019-10-01 12:06:16 +0200686 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200687
Victor Stinner022be022019-05-22 23:58:50 +0200688 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200689 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200690 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200691 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200692 config->dev_mode = 0;
693 config->install_signal_handlers = 0;
694 config->use_hash_seed = 0;
695 config->faulthandler = 0;
696 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200697 config->pathconfig_warnings = 0;
698#ifdef MS_WINDOWS
699 config->legacy_windows_stdio = 0;
700#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200701}
702
703
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200704/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200705PyStatus
706PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200707{
Victor Stinner331a6a52019-05-27 16:39:22 +0200708 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
709 if (_PyStatus_EXCEPTION(status)) {
710 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200711 }
712
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200713 wchar_t *str2;
714 if (str != NULL) {
715 str2 = _PyMem_RawWcsdup(str);
716 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200717 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200718 }
719 }
720 else {
721 str2 = NULL;
722 }
723 PyMem_RawFree(*config_str);
724 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200725 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200726}
727
728
Victor Stinner331a6a52019-05-27 16:39:22 +0200729static PyStatus
730config_set_bytes_string(PyConfig *config, wchar_t **config_str,
731 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200732{
Victor Stinner331a6a52019-05-27 16:39:22 +0200733 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
734 if (_PyStatus_EXCEPTION(status)) {
735 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400736 }
737
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200738 wchar_t *str2;
739 if (str != NULL) {
740 size_t len;
741 str2 = Py_DecodeLocale(str, &len);
742 if (str2 == NULL) {
743 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200744 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200745 }
746 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200747 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200748 }
749 }
750 }
751 else {
752 str2 = NULL;
753 }
754 PyMem_RawFree(*config_str);
755 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200756 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200757}
758
759
Victor Stinner331a6a52019-05-27 16:39:22 +0200760#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
761 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400762
763
Victor Stinner70005ac2019-05-02 15:25:34 -0400764/* Decode str using Py_DecodeLocale() and set the result into *config_str.
765 Pre-initialize Python if needed to ensure that encodings are properly
766 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200767PyStatus
768PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200769 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400770{
Victor Stinner331a6a52019-05-27 16:39:22 +0200771 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400772}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200773
774
Victor Stinner331a6a52019-05-27 16:39:22 +0200775PyStatus
776_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200777{
Victor Stinner331a6a52019-05-27 16:39:22 +0200778 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200779
Victor Stinner331a6a52019-05-27 16:39:22 +0200780 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200781
782#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200783#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200784 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200785 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
786 if (_PyStatus_EXCEPTION(status)) { \
787 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200788 } \
789 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100790#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200791 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200792 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200793 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200794 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200795 } while (0)
796
Victor Stinner6d1c4672019-05-20 11:02:00 +0200797 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100798 COPY_ATTR(isolated);
799 COPY_ATTR(use_environment);
800 COPY_ATTR(dev_mode);
Victor Stinner1def7752020-04-23 03:03:24 +0200801 COPY_ATTR(_use_peg_parser);
Victor Stinner6c785c02018-08-01 17:56:14 +0200802 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200803 COPY_ATTR(use_hash_seed);
804 COPY_ATTR(hash_seed);
805 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200806 COPY_ATTR(faulthandler);
807 COPY_ATTR(tracemalloc);
808 COPY_ATTR(import_time);
809 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200810 COPY_ATTR(dump_refs);
811 COPY_ATTR(malloc_stats);
812
Victor Stinner124b9eb2018-08-29 01:29:06 +0200813 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200814 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200815 COPY_WSTR_ATTR(home);
816 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200817
Victor Stinnerae239f62019-05-16 17:02:56 +0200818 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100819 COPY_WSTRLIST(argv);
820 COPY_WSTRLIST(warnoptions);
821 COPY_WSTRLIST(xoptions);
822 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200823 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200824
Victor Stinner124b9eb2018-08-29 01:29:06 +0200825 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700826 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200827 COPY_WSTR_ATTR(prefix);
828 COPY_WSTR_ATTR(base_prefix);
829 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200830 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner81750642020-06-08 19:36:13 +0200831 COPY_WSTR_ATTR(platlibdir);
Victor Stinner6c785c02018-08-01 17:56:14 +0200832
Victor Stinner6c785c02018-08-01 17:56:14 +0200833 COPY_ATTR(site_import);
834 COPY_ATTR(bytes_warning);
835 COPY_ATTR(inspect);
836 COPY_ATTR(interactive);
837 COPY_ATTR(optimization_level);
838 COPY_ATTR(parser_debug);
839 COPY_ATTR(write_bytecode);
840 COPY_ATTR(verbose);
841 COPY_ATTR(quiet);
842 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200843 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200844 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400845 COPY_WSTR_ATTR(filesystem_encoding);
846 COPY_WSTR_ATTR(filesystem_errors);
847 COPY_WSTR_ATTR(stdio_encoding);
848 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200849#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200850 COPY_ATTR(legacy_windows_stdio);
851#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100852 COPY_ATTR(skip_source_first_line);
853 COPY_WSTR_ATTR(run_command);
854 COPY_WSTR_ATTR(run_module);
855 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400856 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200857 COPY_ATTR(pathconfig_warnings);
858 COPY_ATTR(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200859 COPY_ATTR(_isolated_interpreter);
Victor Stinnerdedaac02020-06-08 18:44:50 +0200860 COPY_WSTRLIST(_orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200861
862#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200863#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200864#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200865 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200866}
867
868
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100869static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200870config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100871{
872 PyObject *dict;
873
874 dict = PyDict_New();
875 if (dict == NULL) {
876 return NULL;
877 }
878
879#define SET_ITEM(KEY, EXPR) \
880 do { \
881 PyObject *obj = (EXPR); \
882 if (obj == NULL) { \
883 goto fail; \
884 } \
885 int res = PyDict_SetItemString(dict, (KEY), obj); \
886 Py_DECREF(obj); \
887 if (res < 0) { \
888 goto fail; \
889 } \
890 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100891#define SET_ITEM_INT(ATTR) \
892 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
893#define SET_ITEM_UINT(ATTR) \
894 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100895#define FROM_WSTRING(STR) \
896 ((STR != NULL) ? \
897 PyUnicode_FromWideChar(STR, -1) \
898 : (Py_INCREF(Py_None), Py_None))
899#define SET_ITEM_WSTR(ATTR) \
900 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
901#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200902 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100903
Victor Stinner6d1c4672019-05-20 11:02:00 +0200904 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100905 SET_ITEM_INT(isolated);
906 SET_ITEM_INT(use_environment);
907 SET_ITEM_INT(dev_mode);
Victor Stinner1def7752020-04-23 03:03:24 +0200908 SET_ITEM_INT(_use_peg_parser);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100909 SET_ITEM_INT(install_signal_handlers);
910 SET_ITEM_INT(use_hash_seed);
911 SET_ITEM_UINT(hash_seed);
912 SET_ITEM_INT(faulthandler);
913 SET_ITEM_INT(tracemalloc);
914 SET_ITEM_INT(import_time);
915 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100916 SET_ITEM_INT(dump_refs);
917 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400918 SET_ITEM_WSTR(filesystem_encoding);
919 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100920 SET_ITEM_WSTR(pycache_prefix);
921 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200922 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100923 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100924 SET_ITEM_WSTRLIST(xoptions);
925 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200926 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100927 SET_ITEM_WSTR(home);
928 SET_ITEM_WSTRLIST(module_search_paths);
929 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700930 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100931 SET_ITEM_WSTR(prefix);
932 SET_ITEM_WSTR(base_prefix);
933 SET_ITEM_WSTR(exec_prefix);
934 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinner81750642020-06-08 19:36:13 +0200935 SET_ITEM_WSTR(platlibdir);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100936 SET_ITEM_INT(site_import);
937 SET_ITEM_INT(bytes_warning);
938 SET_ITEM_INT(inspect);
939 SET_ITEM_INT(interactive);
940 SET_ITEM_INT(optimization_level);
941 SET_ITEM_INT(parser_debug);
942 SET_ITEM_INT(write_bytecode);
943 SET_ITEM_INT(verbose);
944 SET_ITEM_INT(quiet);
945 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200946 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100947 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400948 SET_ITEM_WSTR(stdio_encoding);
949 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100950#ifdef MS_WINDOWS
951 SET_ITEM_INT(legacy_windows_stdio);
952#endif
953 SET_ITEM_INT(skip_source_first_line);
954 SET_ITEM_WSTR(run_command);
955 SET_ITEM_WSTR(run_module);
956 SET_ITEM_WSTR(run_filename);
957 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400958 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200959 SET_ITEM_INT(pathconfig_warnings);
960 SET_ITEM_INT(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200961 SET_ITEM_INT(_isolated_interpreter);
Victor Stinnerdedaac02020-06-08 18:44:50 +0200962 SET_ITEM_WSTRLIST(_orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100963
964 return dict;
965
966fail:
967 Py_DECREF(dict);
968 return NULL;
969
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100970#undef FROM_WSTRING
971#undef SET_ITEM
972#undef SET_ITEM_INT
973#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100974#undef SET_ITEM_WSTR
975#undef SET_ITEM_WSTRLIST
976}
977
978
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100979static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200980config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200981{
Victor Stinner20004952019-03-26 02:31:11 +0100982 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200983}
984
985
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100986/* Get a copy of the environment variable as wchar_t*.
987 Return 0 on success, but *dest can be NULL.
988 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200989static PyStatus
990config_get_env_dup(PyConfig *config,
991 wchar_t **dest,
992 wchar_t *wname, char *name,
993 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200994{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200995 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100996 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200997
Victor Stinner20004952019-03-26 02:31:11 +0100998 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200999 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001000 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001001 }
1002
1003#ifdef MS_WINDOWS
1004 const wchar_t *var = _wgetenv(wname);
1005 if (!var || var[0] == '\0') {
1006 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001007 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001008 }
1009
Victor Stinner331a6a52019-05-27 16:39:22 +02001010 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +02001011#else
1012 const char *var = getenv(name);
1013 if (!var || var[0] == '\0') {
1014 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001015 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001016 }
1017
Victor Stinner331a6a52019-05-27 16:39:22 +02001018 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001019#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001020}
1021
1022
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001023#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001024 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001025
1026
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001027static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001028config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001029{
Victor Stinner022be022019-05-22 23:58:50 +02001030 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1031 /* Python and Isolated configuration ignore global variables */
1032 return;
1033 }
1034
Victor Stinner6c785c02018-08-01 17:56:14 +02001035#define COPY_FLAG(ATTR, VALUE) \
1036 if (config->ATTR == -1) { \
1037 config->ATTR = VALUE; \
1038 }
1039#define COPY_NOT_FLAG(ATTR, VALUE) \
1040 if (config->ATTR == -1) { \
1041 config->ATTR = !(VALUE); \
1042 }
1043
Victor Stinner20004952019-03-26 02:31:11 +01001044 COPY_FLAG(isolated, Py_IsolatedFlag);
1045 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001046 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1047 COPY_FLAG(inspect, Py_InspectFlag);
1048 COPY_FLAG(interactive, Py_InteractiveFlag);
1049 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1050 COPY_FLAG(parser_debug, Py_DebugFlag);
1051 COPY_FLAG(verbose, Py_VerboseFlag);
1052 COPY_FLAG(quiet, Py_QuietFlag);
1053#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001054 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1055#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001056 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001057
Victor Stinner6c785c02018-08-01 17:56:14 +02001058 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1059 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1060 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1061 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1062
Victor Stinner6c785c02018-08-01 17:56:14 +02001063#undef COPY_FLAG
1064#undef COPY_NOT_FLAG
1065}
1066
1067
1068/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001069static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001070config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001071{
1072#define COPY_FLAG(ATTR, VAR) \
1073 if (config->ATTR != -1) { \
1074 VAR = config->ATTR; \
1075 }
1076#define COPY_NOT_FLAG(ATTR, VAR) \
1077 if (config->ATTR != -1) { \
1078 VAR = !config->ATTR; \
1079 }
1080
Victor Stinner20004952019-03-26 02:31:11 +01001081 COPY_FLAG(isolated, Py_IsolatedFlag);
1082 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001083 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1084 COPY_FLAG(inspect, Py_InspectFlag);
1085 COPY_FLAG(interactive, Py_InteractiveFlag);
1086 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1087 COPY_FLAG(parser_debug, Py_DebugFlag);
1088 COPY_FLAG(verbose, Py_VerboseFlag);
1089 COPY_FLAG(quiet, Py_QuietFlag);
1090#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001091 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1092#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001093 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001094
Victor Stinner6c785c02018-08-01 17:56:14 +02001095 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1096 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1097 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1098 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1099
Victor Stinner6c785c02018-08-01 17:56:14 +02001100 /* Random or non-zero hash seed */
1101 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1102 config->hash_seed != 0);
1103
1104#undef COPY_FLAG
1105#undef COPY_NOT_FLAG
1106}
1107
1108
1109/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1110 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001111static PyStatus
1112config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001113{
Victor Stinner331a6a52019-05-27 16:39:22 +02001114 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001115
Victor Stinner6c785c02018-08-01 17:56:14 +02001116 /* If Py_SetProgramName() was called, use its value */
1117 const wchar_t *program_name = _Py_path_config.program_name;
1118 if (program_name != NULL) {
1119 config->program_name = _PyMem_RawWcsdup(program_name);
1120 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001121 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001122 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001123 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001124 }
1125
1126#ifdef __APPLE__
1127 /* On MacOS X, when the Python interpreter is embedded in an
1128 application bundle, it gets executed by a bootstrapping script
1129 that does os.execve() with an argv[0] that's different from the
1130 actual Python executable. This is needed to keep the Finder happy,
1131 or rather, to work around Apple's overly strict requirements of
1132 the process name. However, we still need a usable sys.executable,
1133 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001134 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001135 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001136 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001137 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001138 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1139 "PYTHONEXECUTABLE environment variable");
1140 if (_PyStatus_EXCEPTION(status)) {
1141 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001142 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001143 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001144 }
1145#ifdef WITH_NEXT_FRAMEWORK
1146 else {
1147 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1148 if (pyvenv_launcher && *pyvenv_launcher) {
1149 /* Used by Mac/Tools/pythonw.c to forward
1150 * the argv0 of the stub executable
1151 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001152 status = CONFIG_SET_BYTES_STR(config,
1153 &config->program_name,
1154 pyvenv_launcher,
1155 "__PYVENV_LAUNCHER__ environment variable");
1156 if (_PyStatus_EXCEPTION(status)) {
1157 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001158 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001159
1160 /*
1161 * This environment variable is used to communicate between
1162 * the stub launcher and the real interpreter and isn't needed
1163 * beyond this point.
1164 *
1165 * Clean up to avoid problems when launching other programs
1166 * later on.
1167 */
1168 (void)unsetenv("__PYVENV_LAUNCHER__");
1169
Victor Stinner331a6a52019-05-27 16:39:22 +02001170 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001171 }
1172 }
1173#endif /* WITH_NEXT_FRAMEWORK */
1174#endif /* __APPLE__ */
1175
Victor Stinnerfed02e12019-05-17 11:12:09 +02001176 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001177 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001178 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1179 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1180 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001181 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001182 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001183 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001184 }
1185
Victor Stinnerfed02e12019-05-17 11:12:09 +02001186 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001187#ifdef MS_WINDOWS
1188 const wchar_t *default_program_name = L"python";
1189#else
1190 const wchar_t *default_program_name = L"python3";
1191#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001192 status = PyConfig_SetString(config, &config->program_name,
1193 default_program_name);
1194 if (_PyStatus_EXCEPTION(status)) {
1195 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001196 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001197 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001198}
1199
Victor Stinner331a6a52019-05-27 16:39:22 +02001200static PyStatus
1201config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001202{
1203 assert(config->executable == NULL);
1204
1205 /* If Py_SetProgramFullPath() was called, use its value */
1206 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1207 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001208 PyStatus status = PyConfig_SetString(config,
1209 &config->executable,
1210 program_full_path);
1211 if (_PyStatus_EXCEPTION(status)) {
1212 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001213 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001214 return _PyStatus_OK();
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 Stinner6c785c02018-08-01 17:56:14 +02001218
Victor Stinner4fffd382019-03-06 01:44:31 +01001219
Victor Stinner6c785c02018-08-01 17:56:14 +02001220static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001221config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001222{
Victor Stinner74f65682019-03-15 15:08:05 +01001223 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001224}
1225
1226
Victor Stinner331a6a52019-05-27 16:39:22 +02001227static PyStatus
1228config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001229{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001230 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001231
1232 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001233 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001234 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001235 PyStatus status = PyConfig_SetString(config, &config->home, home);
1236 if (_PyStatus_EXCEPTION(status)) {
1237 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001238 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001239 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001240 }
1241
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001242 return CONFIG_GET_ENV_DUP(config, &config->home,
1243 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001244}
1245
1246
Victor Stinner331a6a52019-05-27 16:39:22 +02001247static PyStatus
1248config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001249{
Victor Stinner331a6a52019-05-27 16:39:22 +02001250 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001251
1252 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1253 /* Convert a text seed to a numeric one */
1254 if (seed_text && strcmp(seed_text, "random") != 0) {
1255 const char *endptr = seed_text;
1256 unsigned long seed;
1257 errno = 0;
1258 seed = strtoul(seed_text, (char **)&endptr, 10);
1259 if (*endptr != '\0'
1260 || seed > 4294967295UL
1261 || (errno == ERANGE && seed == ULONG_MAX))
1262 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001263 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001264 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001265 }
1266 /* Use a specific hash */
1267 config->use_hash_seed = 1;
1268 config->hash_seed = seed;
1269 }
1270 else {
1271 /* Use a random hash */
1272 config->use_hash_seed = 0;
1273 config->hash_seed = 0;
1274 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001275 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001276}
1277
1278
Victor Stinner6c785c02018-08-01 17:56:14 +02001279static int
1280config_wstr_to_int(const wchar_t *wstr, int *result)
1281{
1282 const wchar_t *endptr = wstr;
1283 errno = 0;
1284 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1285 if (*endptr != '\0' || errno == ERANGE) {
1286 return -1;
1287 }
1288 if (value < INT_MIN || value > INT_MAX) {
1289 return -1;
1290 }
1291
1292 *result = (int)value;
1293 return 0;
1294}
1295
1296
Victor Stinner331a6a52019-05-27 16:39:22 +02001297static PyStatus
1298config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001299{
Victor Stinner331a6a52019-05-27 16:39:22 +02001300 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001301 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001302
Victor Stinner6c785c02018-08-01 17:56:14 +02001303 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001304 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1305 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1306 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1307 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001308
1309 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001310 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001311 if (dont_write_bytecode) {
1312 config->write_bytecode = 0;
1313 }
1314
1315 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001316 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001317 if (no_user_site_directory) {
1318 config->user_site_directory = 0;
1319 }
1320
1321 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001322 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001323 if (unbuffered_stdio) {
1324 config->buffered_stdio = 0;
1325 }
1326
1327#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001328 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001329 "PYTHONLEGACYWINDOWSSTDIO");
1330#endif
1331
Victor Stinner331a6a52019-05-27 16:39:22 +02001332 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001333 config->dump_refs = 1;
1334 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001335 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001336 config->malloc_stats = 1;
1337 }
1338
Victor Stinner331a6a52019-05-27 16:39:22 +02001339 if (config->pythonpath_env == NULL) {
1340 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1341 L"PYTHONPATH", "PYTHONPATH");
1342 if (_PyStatus_EXCEPTION(status)) {
1343 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001344 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001345 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001346
Victor Stinner81750642020-06-08 19:36:13 +02001347 if(config->platlibdir == NULL) {
1348 status = CONFIG_GET_ENV_DUP(config, &config->platlibdir,
1349 L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR");
1350 if (_PyStatus_EXCEPTION(status)) {
1351 return status;
1352 }
1353 }
1354
Victor Stinner6c785c02018-08-01 17:56:14 +02001355 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001356 status = config_init_hash_seed(config);
1357 if (_PyStatus_EXCEPTION(status)) {
1358 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001359 }
1360 }
1361
Victor Stinner331a6a52019-05-27 16:39:22 +02001362 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001363}
1364
1365
Victor Stinner331a6a52019-05-27 16:39:22 +02001366static PyStatus
1367config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001368{
1369 int nframe;
1370 int valid;
1371
Victor Stinner331a6a52019-05-27 16:39:22 +02001372 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001373 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001374 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001375 valid = (nframe >= 0);
1376 }
1377 else {
1378 valid = 0;
1379 }
1380 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001381 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001382 }
1383 config->tracemalloc = nframe;
1384 }
1385
1386 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1387 if (xoption) {
1388 const wchar_t *sep = wcschr(xoption, L'=');
1389 if (sep) {
1390 if (!config_wstr_to_int(sep + 1, &nframe)) {
1391 valid = (nframe >= 0);
1392 }
1393 else {
1394 valid = 0;
1395 }
1396 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001397 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1398 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001399 }
1400 }
1401 else {
1402 /* -X tracemalloc behaves as -X tracemalloc=1 */
1403 nframe = 1;
1404 }
1405 config->tracemalloc = nframe;
1406 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001407 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001408}
1409
1410
Victor Stinner331a6a52019-05-27 16:39:22 +02001411static PyStatus
1412config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001413{
1414 assert(config->pycache_prefix == NULL);
1415
1416 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1417 if (xoption) {
1418 const wchar_t *sep = wcschr(xoption, L'=');
1419 if (sep && wcslen(sep) > 1) {
1420 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1421 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001422 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001423 }
1424 }
1425 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001426 // PYTHONPYCACHEPREFIX env var ignored
1427 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001428 config->pycache_prefix = NULL;
1429 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001430 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001431 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001432
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001433 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1434 L"PYTHONPYCACHEPREFIX",
1435 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001436}
1437
1438
Victor Stinner331a6a52019-05-27 16:39:22 +02001439static PyStatus
1440config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001441{
1442 /* More complex options configured by env var and -X option */
1443 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001444 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001445 || config_get_xoption(config, L"faulthandler")) {
1446 config->faulthandler = 1;
1447 }
1448 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001449 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001450 || config_get_xoption(config, L"importtime")) {
1451 config->import_time = 1;
1452 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001453
Pablo Galindoc5fc1562020-04-22 23:29:27 +01001454 if (config_get_env(config, "PYTHONOLDPARSER")
1455 || config_get_xoption(config, L"oldparser")) {
Victor Stinner1def7752020-04-23 03:03:24 +02001456 config->_use_peg_parser = 0;
Pablo Galindoc5fc1562020-04-22 23:29:27 +01001457 }
1458
Victor Stinner331a6a52019-05-27 16:39:22 +02001459 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001460 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001461 status = config_init_tracemalloc(config);
1462 if (_PyStatus_EXCEPTION(status)) {
1463 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001464 }
1465 }
1466
1467 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001468 status = config_init_pycache_prefix(config);
1469 if (_PyStatus_EXCEPTION(status)) {
1470 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001471 }
1472 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001473 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001474}
1475
1476
Victor Stinner709d23d2019-05-02 14:56:30 -04001477static const wchar_t *
Andy Lesteraa450a02020-03-07 11:36:04 -06001478config_get_stdio_errors(void)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001479{
1480#ifndef MS_WINDOWS
1481 const char *loc = setlocale(LC_CTYPE, NULL);
1482 if (loc != NULL) {
1483 /* surrogateescape is the default in the legacy C and POSIX locales */
1484 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001485 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001486 }
1487
1488#ifdef PY_COERCE_C_LOCALE
1489 /* surrogateescape is the default in locale coercion target locales */
1490 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001491 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001492 }
1493#endif
1494 }
1495
Victor Stinner709d23d2019-05-02 14:56:30 -04001496 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001497#else
1498 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001499 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001500#endif
1501}
1502
1503
Victor Stinner331a6a52019-05-27 16:39:22 +02001504static PyStatus
1505config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001506{
1507#ifdef MS_WINDOWS
1508 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001509 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001510 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001511#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001512 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001513#else
1514 const char *encoding = nl_langinfo(CODESET);
1515 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001516 return _PyStatus_ERR("failed to get the locale encoding: "
1517 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001518 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001519 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001520 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001521 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001522 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001523#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001524}
1525
1526
Victor Stinner331a6a52019-05-27 16:39:22 +02001527static PyStatus
1528config_init_stdio_encoding(PyConfig *config,
1529 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001530{
Victor Stinner331a6a52019-05-27 16:39:22 +02001531 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001532
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001533 /* If Py_SetStandardStreamEncoding() have been called, use these
1534 parameters. */
1535 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001536 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1537 _Py_StandardStreamEncoding,
1538 "_Py_StandardStreamEncoding");
1539 if (_PyStatus_EXCEPTION(status)) {
1540 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001541 }
1542 }
1543
1544 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001545 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1546 _Py_StandardStreamErrors,
1547 "_Py_StandardStreamErrors");
1548 if (_PyStatus_EXCEPTION(status)) {
1549 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001550 }
1551 }
1552
1553 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001554 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001555 }
1556
1557 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001558 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001559 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001560 char *pythonioencoding = _PyMem_RawStrdup(opt);
1561 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001562 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001563 }
1564
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001565 char *errors = strchr(pythonioencoding, ':');
1566 if (errors) {
1567 *errors = '\0';
1568 errors++;
1569 if (!errors[0]) {
1570 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001571 }
1572 }
1573
1574 /* Does PYTHONIOENCODING contain an encoding? */
1575 if (pythonioencoding[0]) {
1576 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001577 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1578 pythonioencoding,
1579 "PYTHONIOENCODING environment variable");
1580 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001581 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001582 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001583 }
1584 }
1585
1586 /* If the encoding is set but not the error handler,
1587 use "strict" error handler by default.
1588 PYTHONIOENCODING=latin1 behaves as
1589 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001590 if (!errors) {
1591 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001592 }
1593 }
1594
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001595 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001596 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1597 errors,
1598 "PYTHONIOENCODING environment variable");
1599 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001600 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001601 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001602 }
1603 }
1604
1605 PyMem_RawFree(pythonioencoding);
1606 }
1607
1608 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001609 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001610 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001611 status = PyConfig_SetString(config, &config->stdio_encoding,
1612 L"utf-8");
1613 if (_PyStatus_EXCEPTION(status)) {
1614 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001615 }
1616 }
1617 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001618 status = PyConfig_SetString(config, &config->stdio_errors,
1619 L"surrogateescape");
1620 if (_PyStatus_EXCEPTION(status)) {
1621 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001622 }
1623 }
1624 }
1625
1626 /* Choose the default error handler based on the current locale. */
1627 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001628 status = config_get_locale_encoding(config, &config->stdio_encoding);
1629 if (_PyStatus_EXCEPTION(status)) {
1630 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001631 }
1632 }
1633 if (config->stdio_errors == NULL) {
Andy Lesteraa450a02020-03-07 11:36:04 -06001634 const wchar_t *errors = config_get_stdio_errors();
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001635 assert(errors != NULL);
1636
Victor Stinner331a6a52019-05-27 16:39:22 +02001637 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1638 if (_PyStatus_EXCEPTION(status)) {
1639 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001640 }
1641 }
1642
Victor Stinner331a6a52019-05-27 16:39:22 +02001643 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001644}
1645
1646
Victor Stinner331a6a52019-05-27 16:39:22 +02001647static PyStatus
1648config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001649{
Victor Stinner331a6a52019-05-27 16:39:22 +02001650 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001651
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001652 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001653#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001654 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001655#else
Victor Stinnere2510952019-05-02 11:28:57 -04001656
1657#ifdef MS_WINDOWS
1658 if (preconfig->legacy_windows_fs_encoding) {
1659 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001660 status = PyConfig_SetString(config, &config->filesystem_encoding,
1661 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001662 }
1663 else
1664#endif
Victor Stinner20004952019-03-26 02:31:11 +01001665 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001666 status = PyConfig_SetString(config, &config->filesystem_encoding,
1667 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001668 }
Victor Stinnere2510952019-05-02 11:28:57 -04001669#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001670 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001671 status = PyConfig_SetString(config, &config->filesystem_encoding,
1672 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001673 }
Victor Stinnere2510952019-05-02 11:28:57 -04001674#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001675 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001676#ifdef MS_WINDOWS
1677 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001678 status = PyConfig_SetString(config, &config->filesystem_encoding,
1679 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001680#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001681 status = config_get_locale_encoding(config,
1682 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001683#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001684 }
Victor Stinnere2510952019-05-02 11:28:57 -04001685#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001686
Victor Stinner331a6a52019-05-27 16:39:22 +02001687 if (_PyStatus_EXCEPTION(status)) {
1688 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001689 }
1690 }
1691
1692 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001693 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001694#ifdef MS_WINDOWS
1695 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001696 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001697 }
1698 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001699 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001700 }
1701#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001702 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001703#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001704 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1705 if (_PyStatus_EXCEPTION(status)) {
1706 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001707 }
1708 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001709 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001710}
1711
1712
Victor Stinner331a6a52019-05-27 16:39:22 +02001713static PyStatus
1714config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001715{
Victor Stinner331a6a52019-05-27 16:39:22 +02001716 PyStatus status;
1717 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001718
Victor Stinner20004952019-03-26 02:31:11 +01001719 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001720 status = config_read_env_vars(config);
1721 if (_PyStatus_EXCEPTION(status)) {
1722 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001723 }
1724 }
1725
1726 /* -X options */
1727 if (config_get_xoption(config, L"showrefcount")) {
1728 config->show_ref_count = 1;
1729 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001730
Victor Stinner331a6a52019-05-27 16:39:22 +02001731 status = config_read_complex_options(config);
1732 if (_PyStatus_EXCEPTION(status)) {
1733 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001734 }
1735
Victor Stinner6c785c02018-08-01 17:56:14 +02001736 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001737 status = config_init_home(config);
1738 if (_PyStatus_EXCEPTION(status)) {
1739 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001740 }
1741 }
1742
Steve Dower177a41a2018-11-17 20:41:48 -08001743 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001744 status = config_init_executable(config);
1745 if (_PyStatus_EXCEPTION(status)) {
1746 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001747 }
1748 }
1749
Victor Stinner81750642020-06-08 19:36:13 +02001750 if(config->platlibdir == NULL) {
1751 status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR,
1752 "PLATLIBDIR macro");
1753 if (_PyStatus_EXCEPTION(status)) {
1754 return status;
1755 }
1756 }
1757
Victor Stinner6c785c02018-08-01 17:56:14 +02001758 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001759 status = _PyConfig_InitPathConfig(config);
1760 if (_PyStatus_EXCEPTION(status)) {
1761 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001762 }
1763 }
1764
1765 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001766 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001767 if (config->faulthandler < 0) {
1768 config->faulthandler = 1;
1769 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001770 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001771 if (config->faulthandler < 0) {
1772 config->faulthandler = 0;
1773 }
1774 if (config->tracemalloc < 0) {
1775 config->tracemalloc = 0;
1776 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001777 if (config->use_hash_seed < 0) {
1778 config->use_hash_seed = 0;
1779 config->hash_seed = 0;
1780 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001781
Victor Stinner70fead22018-08-29 13:45:34 +02001782 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001783 status = config_init_fs_encoding(config, preconfig);
1784 if (_PyStatus_EXCEPTION(status)) {
1785 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001786 }
1787 }
1788
Victor Stinner331a6a52019-05-27 16:39:22 +02001789 status = config_init_stdio_encoding(config, preconfig);
1790 if (_PyStatus_EXCEPTION(status)) {
1791 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001792 }
1793
Victor Stinner62599762019-03-15 16:03:23 +01001794 if (config->argv.length < 1) {
1795 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001796 status = PyWideStringList_Append(&config->argv, L"");
1797 if (_PyStatus_EXCEPTION(status)) {
1798 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001799 }
1800 }
Victor Stinner870b0352019-05-17 03:15:12 +02001801
1802 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001803 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1804 L"default");
1805 if (_PyStatus_EXCEPTION(status)) {
1806 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001807 }
1808 }
1809
1810 if (config->configure_c_stdio < 0) {
1811 config->configure_c_stdio = 1;
1812 }
1813
Victor Stinner331a6a52019-05-27 16:39:22 +02001814 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001815}
Victor Stinner5ed69952018-11-06 15:59:52 +01001816
1817
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001818static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001819config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001820{
1821#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1822 /* don't translate newlines (\r\n <=> \n) */
1823 _setmode(fileno(stdin), O_BINARY);
1824 _setmode(fileno(stdout), O_BINARY);
1825 _setmode(fileno(stderr), O_BINARY);
1826#endif
1827
1828 if (!config->buffered_stdio) {
1829#ifdef HAVE_SETVBUF
1830 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1831 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1832 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1833#else /* !HAVE_SETVBUF */
1834 setbuf(stdin, (char *)NULL);
1835 setbuf(stdout, (char *)NULL);
1836 setbuf(stderr, (char *)NULL);
1837#endif /* !HAVE_SETVBUF */
1838 }
1839 else if (config->interactive) {
1840#ifdef MS_WINDOWS
1841 /* Doesn't have to have line-buffered -- use unbuffered */
1842 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1843 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1844#else /* !MS_WINDOWS */
1845#ifdef HAVE_SETVBUF
1846 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1847 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1848#endif /* HAVE_SETVBUF */
1849#endif /* !MS_WINDOWS */
1850 /* Leave stderr alone - it should be unbuffered anyway. */
1851 }
1852}
1853
1854
1855/* Write the configuration:
1856
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001857 - set Py_xxx global configuration variables
1858 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinnerdedaac02020-06-08 18:44:50 +02001859PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +02001860_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001861{
Victor Stinner331a6a52019-05-27 16:39:22 +02001862 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001863
1864 if (config->configure_c_stdio) {
1865 config_init_stdio(config);
1866 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001867
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001868 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001869 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001870 preconfig->isolated = config->isolated;
1871 preconfig->use_environment = config->use_environment;
1872 preconfig->dev_mode = config->dev_mode;
Victor Stinnerdedaac02020-06-08 18:44:50 +02001873
1874 if (_Py_SetArgcArgv(config->_orig_argv.length,
1875 config->_orig_argv.items) < 0)
1876 {
1877 return _PyStatus_NO_MEMORY();
1878 }
1879 return _PyStatus_OK();
Victor Stinner5ed69952018-11-06 15:59:52 +01001880}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001881
1882
Victor Stinner331a6a52019-05-27 16:39:22 +02001883/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001884
1885static void
Victor Stinner2f549082019-03-29 15:13:46 +01001886config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001887{
Victor Stinner2f549082019-03-29 15:13:46 +01001888 FILE *f = error ? stderr : stdout;
1889
1890 fprintf(f, usage_line, program);
1891 if (error)
1892 fprintf(f, "Try `python -h' for more information.\n");
1893 else {
1894 fputs(usage_1, f);
1895 fputs(usage_2, f);
1896 fputs(usage_3, f);
1897 fprintf(f, usage_4, (wint_t)DELIM);
1898 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1899 fputs(usage_6, f);
1900 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001901}
1902
1903
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001904/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001905static PyStatus
1906config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001907 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001908{
Victor Stinner331a6a52019-05-27 16:39:22 +02001909 PyStatus status;
1910 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001911 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001912 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001913
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001914 _PyOS_ResetGetOpt();
1915 do {
1916 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001917 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001918 if (c == EOF) {
1919 break;
1920 }
1921
1922 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001923 if (config->run_command == NULL) {
1924 /* -c is the last option; following arguments
1925 that look like options are left for the
1926 command to interpret. */
1927 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1928 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1929 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001930 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001931 }
1932 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1933 command[len - 2] = '\n';
1934 command[len - 1] = 0;
1935 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001936 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001937 break;
1938 }
1939
1940 if (c == 'm') {
1941 /* -m is the last option; following arguments
1942 that look like options are left for the
1943 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001944 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001945 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1946 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001947 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001948 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001949 }
1950 break;
1951 }
1952
1953 switch (c) {
1954 case 0:
1955 // Handle long option.
1956 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001957 if (wcscmp(_PyOS_optarg, L"always") == 0
1958 || wcscmp(_PyOS_optarg, L"never") == 0
1959 || wcscmp(_PyOS_optarg, L"default") == 0)
1960 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001961 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1962 _PyOS_optarg);
1963 if (_PyStatus_EXCEPTION(status)) {
1964 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001965 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001966 } else {
1967 fprintf(stderr, "--check-hash-based-pycs must be one of "
1968 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001969 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001970 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001971 }
1972 break;
1973
1974 case 'b':
1975 config->bytes_warning++;
1976 break;
1977
1978 case 'd':
1979 config->parser_debug++;
1980 break;
1981
1982 case 'i':
1983 config->inspect++;
1984 config->interactive++;
1985 break;
1986
Victor Stinner6dcb5422019-03-05 02:44:12 +01001987 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001988 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001989 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001990 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001991 break;
1992
1993 /* case 'J': reserved for Jython */
1994
1995 case 'O':
1996 config->optimization_level++;
1997 break;
1998
1999 case 'B':
2000 config->write_bytecode = 0;
2001 break;
2002
2003 case 's':
2004 config->user_site_directory = 0;
2005 break;
2006
2007 case 'S':
2008 config->site_import = 0;
2009 break;
2010
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002011 case 't':
2012 /* ignored for backwards compatibility */
2013 break;
2014
2015 case 'u':
2016 config->buffered_stdio = 0;
2017 break;
2018
2019 case 'v':
2020 config->verbose++;
2021 break;
2022
2023 case 'x':
2024 config->skip_source_first_line = 1;
2025 break;
2026
2027 case 'h':
2028 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02002029 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002030 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002031
2032 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01002033 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002034 break;
2035
2036 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002037 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2038 if (_PyStatus_EXCEPTION(status)) {
2039 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002040 }
2041 break;
2042
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002043 case 'q':
2044 config->quiet++;
2045 break;
2046
2047 case 'R':
2048 config->use_hash_seed = 0;
2049 break;
2050
2051 /* This space reserved for other options */
2052
2053 default:
2054 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002055 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002056 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002057 }
2058 } while (1);
2059
Victor Stinner2f549082019-03-29 15:13:46 +01002060 if (print_version) {
2061 printf("Python %s\n",
2062 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002063 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002064 }
2065
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002066 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002067 && _PyOS_optind < argv->length
2068 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002069 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002070 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002071 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002072 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002073 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002074 }
2075 }
2076
2077 if (config->run_command != NULL || config->run_module != NULL) {
2078 /* Backup _PyOS_optind */
2079 _PyOS_optind--;
2080 }
2081
Victor Stinnerae239f62019-05-16 17:02:56 +02002082 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002083
Victor Stinner331a6a52019-05-27 16:39:22 +02002084 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002085}
2086
2087
2088#ifdef MS_WINDOWS
2089# define WCSTOK wcstok_s
2090#else
2091# define WCSTOK wcstok
2092#endif
2093
2094/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002095static PyStatus
2096config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002097{
Victor Stinner331a6a52019-05-27 16:39:22 +02002098 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002099 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2100 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002101 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002102 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002103 if (_PyStatus_EXCEPTION(status)) {
2104 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002105 }
2106
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002107 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002108 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002109 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002110 }
2111
2112
2113 wchar_t *warning, *context = NULL;
2114 for (warning = WCSTOK(env, L",", &context);
2115 warning != NULL;
2116 warning = WCSTOK(NULL, L",", &context))
2117 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002118 status = PyWideStringList_Append(warnoptions, warning);
2119 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002120 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002121 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002122 }
2123 }
2124 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002125 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002126}
2127
2128
Victor Stinner331a6a52019-05-27 16:39:22 +02002129static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002130warnoptions_append(PyConfig *config, PyWideStringList *options,
2131 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002132{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002133 /* config_init_warnoptions() add existing config warnoptions at the end:
2134 ensure that the new option is not already present in this list to
2135 prevent change the options order whne config_init_warnoptions() is
2136 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002137 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002138 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002139 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002140 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002141 if (_PyWideStringList_Find(options, option)) {
2142 /* Already present: do nothing */
2143 return _PyStatus_OK();
2144 }
2145 return PyWideStringList_Append(options, option);
2146}
2147
2148
2149static PyStatus
2150warnoptions_extend(PyConfig *config, PyWideStringList *options,
2151 const PyWideStringList *options2)
2152{
2153 const Py_ssize_t len = options2->length;
2154 wchar_t *const *items = options2->items;
2155
2156 for (Py_ssize_t i = 0; i < len; i++) {
2157 PyStatus status = warnoptions_append(config, options, items[i]);
2158 if (_PyStatus_EXCEPTION(status)) {
2159 return status;
2160 }
2161 }
2162 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002163}
2164
2165
Victor Stinner331a6a52019-05-27 16:39:22 +02002166static PyStatus
2167config_init_warnoptions(PyConfig *config,
2168 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002169 const PyWideStringList *env_warnoptions,
2170 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002171{
Victor Stinner331a6a52019-05-27 16:39:22 +02002172 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002173 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002174
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002175 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002176 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002177 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002178 * - PyConfig.dev_mode: "default" filter
2179 * - PYTHONWARNINGS environment variable
2180 * - '-W' command line options
2181 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2182 * "default::BytesWarning" or "error::BytesWarning" filter
2183 * - early PySys_AddWarnOption() calls
2184 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002185 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002186 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2187 * module works on the basis of "the most recently added filter will be
2188 * checked first", we add the lowest precedence entries first so that later
2189 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002190 */
2191
Victor Stinner20004952019-03-26 02:31:11 +01002192 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002193 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002194 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002195 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002196 }
2197 }
2198
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002199 status = warnoptions_extend(config, &options, env_warnoptions);
2200 if (_PyStatus_EXCEPTION(status)) {
2201 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002202 }
2203
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002204 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2205 if (_PyStatus_EXCEPTION(status)) {
2206 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002207 }
2208
2209 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2210 * don't even try to emit a warning, so we skip setting the filter in that
2211 * case.
2212 */
2213 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002214 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002215 if (config->bytes_warning> 1) {
2216 filter = L"error::BytesWarning";
2217 }
2218 else {
2219 filter = L"default::BytesWarning";
2220 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002221 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002222 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002223 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002224 }
2225 }
Victor Stinner120b7072019-08-23 18:03:08 +01002226
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002227 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002228 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002229 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002230 }
2231
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002232 /* Always add all PyConfig.warnoptions options */
2233 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2234 if (_PyStatus_EXCEPTION(status)) {
2235 goto error;
2236 }
2237
2238 _PyWideStringList_Clear(&config->warnoptions);
2239 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002240 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002241
2242error:
2243 _PyWideStringList_Clear(&options);
2244 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002245}
2246
2247
Victor Stinner331a6a52019-05-27 16:39:22 +02002248static PyStatus
2249config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002250{
Victor Stinner331a6a52019-05-27 16:39:22 +02002251 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002252 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002253
Victor Stinner74f65682019-03-15 15:08:05 +01002254 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002255 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002256 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002257 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2258 if (_PyStatus_EXCEPTION(status)) {
2259 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002260 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002261 }
2262 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002263 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002264 slice.length = cmdline_argv->length - opt_index;
2265 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002266 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2267 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002268 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002269 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002270 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002271
2272 wchar_t *arg0 = NULL;
2273 if (config->run_command != NULL) {
2274 /* Force sys.argv[0] = '-c' */
2275 arg0 = L"-c";
2276 }
2277 else if (config->run_module != NULL) {
2278 /* Force sys.argv[0] = '-m'*/
2279 arg0 = L"-m";
2280 }
Victor Stinner3939c322019-06-25 15:02:43 +02002281
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002282 if (arg0 != NULL) {
2283 arg0 = _PyMem_RawWcsdup(arg0);
2284 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002285 _PyWideStringList_Clear(&config_argv);
2286 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002287 }
2288
Victor Stinnerfa153762019-03-20 04:25:38 +01002289 PyMem_RawFree(config_argv.items[0]);
2290 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002291 }
2292
Victor Stinner331a6a52019-05-27 16:39:22 +02002293 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002294 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002295 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002296}
2297
2298
Victor Stinner331a6a52019-05-27 16:39:22 +02002299static PyStatus
2300core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002301{
Victor Stinner331a6a52019-05-27 16:39:22 +02002302 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002303
Victor Stinnercab5d072019-05-17 19:01:14 +02002304 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002305 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2306 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002307 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002308 }
2309
Victor Stinner331a6a52019-05-27 16:39:22 +02002310 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002311
2312 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2313 if (_PyStatus_EXCEPTION(status)) {
2314 return status;
2315 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002316
Victor Stinner331a6a52019-05-27 16:39:22 +02002317 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002318
Victor Stinner331a6a52019-05-27 16:39:22 +02002319 status = _PyPreCmdline_Read(precmdline, &preconfig);
2320 if (_PyStatus_EXCEPTION(status)) {
2321 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002322 }
2323
Victor Stinner331a6a52019-05-27 16:39:22 +02002324 status = _PyPreCmdline_SetConfig(precmdline, config);
2325 if (_PyStatus_EXCEPTION(status)) {
2326 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002327 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002328 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002329}
2330
2331
Victor Stinner3939c322019-06-25 15:02:43 +02002332/* Get run_filename absolute path */
2333static PyStatus
2334config_run_filename_abspath(PyConfig *config)
2335{
2336 if (!config->run_filename) {
2337 return _PyStatus_OK();
2338 }
2339
2340#ifndef MS_WINDOWS
2341 if (_Py_isabs(config->run_filename)) {
2342 /* path is already absolute */
2343 return _PyStatus_OK();
2344 }
2345#endif
2346
2347 wchar_t *abs_filename;
2348 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2349 /* failed to get the absolute path of the command line filename:
2350 ignore the error, keep the relative path */
2351 return _PyStatus_OK();
2352 }
2353 if (abs_filename == NULL) {
2354 return _PyStatus_NO_MEMORY();
2355 }
2356
2357 PyMem_RawFree(config->run_filename);
2358 config->run_filename = abs_filename;
2359 return _PyStatus_OK();
2360}
2361
2362
Victor Stinner331a6a52019-05-27 16:39:22 +02002363static PyStatus
2364config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002365{
Victor Stinner331a6a52019-05-27 16:39:22 +02002366 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002367 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2368 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2369 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002370
Victor Stinnerae239f62019-05-16 17:02:56 +02002371 if (config->parse_argv < 0) {
2372 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002373 }
Victor Stinner870b0352019-05-17 03:15:12 +02002374
Victor Stinnerfed02e12019-05-17 11:12:09 +02002375 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002376 status = config_init_program_name(config);
2377 if (_PyStatus_EXCEPTION(status)) {
2378 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002379 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002380 }
Victor Stinner2f549082019-03-29 15:13:46 +01002381
Victor Stinnerae239f62019-05-16 17:02:56 +02002382 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002383 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002384 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2385 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002386 goto done;
2387 }
2388
Victor Stinner3939c322019-06-25 15:02:43 +02002389 status = config_run_filename_abspath(config);
2390 if (_PyStatus_EXCEPTION(status)) {
2391 goto done;
2392 }
2393
Victor Stinner331a6a52019-05-27 16:39:22 +02002394 status = config_update_argv(config, opt_index);
2395 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002396 goto done;
2397 }
Victor Stinner2f549082019-03-29 15:13:46 +01002398 }
Victor Stinner3939c322019-06-25 15:02:43 +02002399 else {
2400 status = config_run_filename_abspath(config);
2401 if (_PyStatus_EXCEPTION(status)) {
2402 goto done;
2403 }
2404 }
Victor Stinner2f549082019-03-29 15:13:46 +01002405
Victor Stinner2f549082019-03-29 15:13:46 +01002406 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002407 status = config_init_env_warnoptions(config, &env_warnoptions);
2408 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002409 goto done;
2410 }
2411 }
2412
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002413 /* Handle early PySys_AddWarnOption() calls */
2414 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2415 if (_PyStatus_EXCEPTION(status)) {
2416 goto done;
2417 }
2418
Victor Stinner331a6a52019-05-27 16:39:22 +02002419 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002420 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002421 &env_warnoptions,
2422 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002423 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002424 goto done;
2425 }
2426
Victor Stinner331a6a52019-05-27 16:39:22 +02002427 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002428
2429done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002430 _PyWideStringList_Clear(&cmdline_warnoptions);
2431 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002432 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002433 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002434}
2435
2436
Victor Stinner331a6a52019-05-27 16:39:22 +02002437PyStatus
2438_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002439{
Victor Stinner331a6a52019-05-27 16:39:22 +02002440 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2441 if (_PyStatus_EXCEPTION(status)) {
2442 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002443 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002444
Victor Stinner5f38b842019-05-01 02:30:12 +02002445 return _PyArgv_AsWstrList(args, &config->argv);
2446}
2447
2448
Victor Stinner70005ac2019-05-02 15:25:34 -04002449/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2450 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002451PyStatus
2452PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002453{
2454 _PyArgv args = {
2455 .argc = argc,
2456 .use_bytes_argv = 1,
2457 .bytes_argv = argv,
2458 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002459 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002460}
2461
2462
Victor Stinner331a6a52019-05-27 16:39:22 +02002463PyStatus
2464PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002465{
2466 _PyArgv args = {
2467 .argc = argc,
2468 .use_bytes_argv = 0,
2469 .bytes_argv = NULL,
2470 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002471 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002472}
2473
2474
Victor Stinner36242fd2019-07-01 19:13:50 +02002475PyStatus
2476PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2477 Py_ssize_t length, wchar_t **items)
2478{
2479 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2480 if (_PyStatus_EXCEPTION(status)) {
2481 return status;
2482 }
2483
2484 PyWideStringList list2 = {.length = length, .items = items};
2485 if (_PyWideStringList_Copy(list, &list2) < 0) {
2486 return _PyStatus_NO_MEMORY();
2487 }
2488 return _PyStatus_OK();
2489}
2490
2491
Victor Stinner331a6a52019-05-27 16:39:22 +02002492/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002493
2494 * Command line arguments
2495 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002496 * Py_xxx global configuration variables
2497
2498 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002499PyStatus
2500PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002501{
Victor Stinner331a6a52019-05-27 16:39:22 +02002502 PyStatus status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002503
Victor Stinner331a6a52019-05-27 16:39:22 +02002504 status = _Py_PreInitializeFromConfig(config, NULL);
2505 if (_PyStatus_EXCEPTION(status)) {
2506 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002507 }
2508
Victor Stinner331a6a52019-05-27 16:39:22 +02002509 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002510
Victor Stinnerdedaac02020-06-08 18:44:50 +02002511 if (config->_orig_argv.length == 0
2512 && !(config->argv.length == 1
2513 && wcscmp(config->argv.items[0], L"") == 0))
2514 {
2515 if (_PyWideStringList_Copy(&config->_orig_argv, &config->argv) < 0) {
2516 return _PyStatus_NO_MEMORY();
2517 }
Victor Stinnercab5d072019-05-17 19:01:14 +02002518 }
2519
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002520 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002521 status = core_read_precmdline(config, &precmdline);
2522 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002523 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002524 }
2525
Victor Stinner870b0352019-05-17 03:15:12 +02002526 assert(config->isolated >= 0);
2527 if (config->isolated) {
2528 config->use_environment = 0;
2529 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002530 }
2531
Victor Stinner331a6a52019-05-27 16:39:22 +02002532 status = config_read_cmdline(config);
2533 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002534 goto done;
2535 }
2536
Victor Stinner120b7072019-08-23 18:03:08 +01002537 /* Handle early PySys_AddXOption() calls */
2538 status = _PySys_ReadPreinitXOptions(config);
2539 if (_PyStatus_EXCEPTION(status)) {
2540 goto done;
2541 }
2542
Victor Stinner331a6a52019-05-27 16:39:22 +02002543 status = config_read(config);
2544 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002545 goto done;
2546 }
2547
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002548 /* Check config consistency */
2549 assert(config->isolated >= 0);
2550 assert(config->use_environment >= 0);
2551 assert(config->dev_mode >= 0);
Victor Stinner1def7752020-04-23 03:03:24 +02002552 assert(config->_use_peg_parser >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002553 assert(config->install_signal_handlers >= 0);
2554 assert(config->use_hash_seed >= 0);
2555 assert(config->faulthandler >= 0);
2556 assert(config->tracemalloc >= 0);
2557 assert(config->site_import >= 0);
2558 assert(config->bytes_warning >= 0);
2559 assert(config->inspect >= 0);
2560 assert(config->interactive >= 0);
2561 assert(config->optimization_level >= 0);
2562 assert(config->parser_debug >= 0);
2563 assert(config->write_bytecode >= 0);
2564 assert(config->verbose >= 0);
2565 assert(config->quiet >= 0);
2566 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002567 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002568 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002569 assert(config->buffered_stdio >= 0);
2570 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002571 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002572 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2573 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002574 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2575 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2576 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002577 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002578 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002579 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002580 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002581 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002582 assert(config->prefix != NULL);
2583 assert(config->base_prefix != NULL);
2584 assert(config->exec_prefix != NULL);
2585 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002586 }
Victor Stinner81750642020-06-08 19:36:13 +02002587 assert(config->platlibdir != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002588 assert(config->filesystem_encoding != NULL);
2589 assert(config->filesystem_errors != NULL);
2590 assert(config->stdio_encoding != NULL);
2591 assert(config->stdio_errors != NULL);
2592#ifdef MS_WINDOWS
2593 assert(config->legacy_windows_stdio >= 0);
2594#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002595 /* -c and -m options are exclusive */
2596 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002597 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002598 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002599 assert(config->pathconfig_warnings >= 0);
Victor Stinnerdedaac02020-06-08 18:44:50 +02002600 assert(_PyWideStringList_CheckConsistency(&config->_orig_argv));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002601
Victor Stinner331a6a52019-05-27 16:39:22 +02002602 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002603
2604done:
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002605 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002606 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002607}
Victor Stinner1075d162019-03-25 23:19:57 +01002608
2609
2610PyObject*
2611_Py_GetConfigsAsDict(void)
2612{
Victor Stinner331a6a52019-05-27 16:39:22 +02002613 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002614 PyObject *dict = NULL;
2615
Victor Stinner331a6a52019-05-27 16:39:22 +02002616 result = PyDict_New();
2617 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002618 goto error;
2619 }
2620
Victor Stinner331a6a52019-05-27 16:39:22 +02002621 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002622 dict = _Py_GetGlobalVariablesAsDict();
2623 if (dict == NULL) {
2624 goto error;
2625 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002626 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002627 goto error;
2628 }
2629 Py_CLEAR(dict);
2630
2631 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002632 PyThreadState *tstate = _PyThreadState_GET();
2633 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002634 dict = _PyPreConfig_AsDict(pre_config);
2635 if (dict == NULL) {
2636 goto error;
2637 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002638 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002639 goto error;
2640 }
2641 Py_CLEAR(dict);
2642
2643 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002644 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinner331a6a52019-05-27 16:39:22 +02002645 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002646 if (dict == NULL) {
2647 goto error;
2648 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002649 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002650 goto error;
2651 }
2652 Py_CLEAR(dict);
2653
Victor Stinner331a6a52019-05-27 16:39:22 +02002654 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002655
2656error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002657 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002658 Py_XDECREF(dict);
2659 return NULL;
2660}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002661
2662
2663static void
2664init_dump_ascii_wstr(const wchar_t *str)
2665{
2666 if (str == NULL) {
2667 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002668 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002669 }
2670
2671 PySys_WriteStderr("'");
2672 for (; *str != L'\0'; str++) {
2673 wchar_t ch = *str;
2674 if (ch == L'\'') {
2675 PySys_WriteStderr("\\'");
2676 } else if (0x20 <= ch && ch < 0x7f) {
2677 PySys_WriteStderr("%lc", ch);
2678 }
2679 else if (ch <= 0xff) {
2680 PySys_WriteStderr("\\x%02x", ch);
2681 }
2682#if SIZEOF_WCHAR_T > 2
2683 else if (ch > 0xffff) {
2684 PySys_WriteStderr("\\U%08x", ch);
2685 }
2686#endif
2687 else {
2688 PySys_WriteStderr("\\u%04x", ch);
2689 }
2690 }
2691 PySys_WriteStderr("'");
2692}
2693
2694
2695/* Dump the Python path configuration into sys.stderr */
2696void
2697_Py_DumpPathConfig(PyThreadState *tstate)
2698{
2699 PyObject *exc_type, *exc_value, *exc_tb;
2700 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2701
2702 PySys_WriteStderr("Python path configuration:\n");
2703
2704#define DUMP_CONFIG(NAME, FIELD) \
2705 do { \
2706 PySys_WriteStderr(" " NAME " = "); \
2707 init_dump_ascii_wstr(config->FIELD); \
2708 PySys_WriteStderr("\n"); \
2709 } while (0)
2710
Victor Stinnerda7933e2020-04-13 03:04:28 +02002711 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002712 DUMP_CONFIG("PYTHONHOME", home);
2713 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2714 DUMP_CONFIG("program name", program_name);
2715 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2716 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2717 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2718 PySys_WriteStderr(" import site = %i\n", config->site_import);
2719#undef DUMP_CONFIG
2720
2721#define DUMP_SYS(NAME) \
2722 do { \
2723 obj = PySys_GetObject(#NAME); \
2724 PySys_FormatStderr(" sys.%s = ", #NAME); \
2725 if (obj != NULL) { \
2726 PySys_FormatStderr("%A", obj); \
2727 } \
2728 else { \
2729 PySys_WriteStderr("(not set)"); \
2730 } \
2731 PySys_FormatStderr("\n"); \
2732 } while (0)
2733
2734 PyObject *obj;
2735 DUMP_SYS(_base_executable);
2736 DUMP_SYS(base_prefix);
2737 DUMP_SYS(base_exec_prefix);
Victor Stinner81750642020-06-08 19:36:13 +02002738 DUMP_SYS(platlibdir);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002739 DUMP_SYS(executable);
2740 DUMP_SYS(prefix);
2741 DUMP_SYS(exec_prefix);
2742#undef DUMP_SYS
2743
2744 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2745 if (sys_path != NULL && PyList_Check(sys_path)) {
2746 PySys_WriteStderr(" sys.path = [\n");
2747 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2748 for (Py_ssize_t i=0; i < len; i++) {
2749 PyObject *path = PyList_GET_ITEM(sys_path, i);
2750 PySys_FormatStderr(" %A,\n", path);
2751 }
2752 PySys_WriteStderr(" ]\n");
2753 }
2754
2755 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2756}