blob: 7bad36ef17b813a0712393aec0119c9ca5c73b4d [file] [log] [blame]
Victor Stinner6c785c02018-08-01 17:56:14 +02001#include "Python.h"
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002#include "osdefs.h" /* DELIM */
Victor Stinner9fc57a32018-11-07 00:44:03 +01003#include "pycore_fileutils.h"
Victor Stinner95e2cbf2019-03-01 16:25:19 +01004#include "pycore_getopt.h"
Victor Stinnerfcdb0272019-09-23 14:45:47 +02005#include "pycore_initconfig.h"
6#include "pycore_pathconfig.h"
7#include "pycore_pyerrors.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01008#include "pycore_pylifecycle.h"
9#include "pycore_pymem.h"
Victor Stinner6d5ee972019-03-23 12:05:43 +010010#include "pycore_pystate.h" /* _PyRuntime */
Victor Stinner95e2cbf2019-03-01 16:25:19 +010011#include <locale.h> /* setlocale() */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020012#ifdef HAVE_LANGINFO_H
Victor Stinner95e2cbf2019-03-01 16:25:19 +010013# include <langinfo.h> /* nl_langinfo(CODESET) */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020014#endif
Victor Stinner95e2cbf2019-03-01 16:25:19 +010015#if defined(MS_WINDOWS) || defined(__CYGWIN__)
16# include <windows.h> /* GetACP() */
17# ifdef HAVE_IO_H
18# include <io.h>
19# endif
20# ifdef HAVE_FCNTL_H
21# include <fcntl.h> /* O_BINARY */
22# endif
Victor Stinnerb2457ef2018-08-29 13:25:36 +020023#endif
24
Victor Stinner6c785c02018-08-01 17:56:14 +020025
Victor Stinner95e2cbf2019-03-01 16:25:19 +010026/* --- Command line options --------------------------------------- */
27
Victor Stinner95e2cbf2019-03-01 16:25:19 +010028/* Short usage message (with %s for argv0) */
29static const char usage_line[] =
30"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
31
32/* Long usage message, split into parts < 512 bytes */
33static const char usage_1[] = "\
34Options and arguments (and corresponding environment variables):\n\
35-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
36 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
37-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
38-c cmd : program passed in as string (terminates option list)\n\
39-d : debug output from parser; also PYTHONDEBUG=x\n\
40-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
41-h : print this help message and exit (also --help)\n\
42";
43static const char usage_2[] = "\
44-i : inspect interactively after running script; forces a prompt even\n\
45 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
46-I : isolate Python from the user's environment (implies -E and -s)\n\
47-m mod : run library module as a script (terminates option list)\n\
48-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
49 .pyc extension; also PYTHONOPTIMIZE=x\n\
50-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
51 .pyc extension\n\
52-q : don't print version and copyright messages on interactive startup\n\
53-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
54-S : don't imply 'import site' on initialization\n\
55";
56static const char usage_3[] = "\
57-u : force the stdout and stderr streams to be unbuffered;\n\
58 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
59-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
60 can be supplied multiple times to increase verbosity\n\
61-V : print the Python version number and exit (also --version)\n\
62 when given twice, print more information about the build\n\
63-W arg : warning control; arg is action:message:category:module:lineno\n\
64 also PYTHONWARNINGS=arg\n\
65-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000066-X opt : set implementation-specific option. The following options are available:\n\
67\n\
68 -X faulthandler: enable faulthandler\n\
69 -X showrefcount: output the total reference count and number of used\n\
70 memory blocks when the program finishes or after each statement in the\n\
71 interactive interpreter. This only works on debug builds\n\
72 -X tracemalloc: start tracing Python memory allocations using the\n\
73 tracemalloc module. By default, only the most recent frame is stored in a\n\
74 traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\
75 traceback limit of NFRAME frames\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000076 -X importtime: show how long each import takes. It shows module name,\n\
77 cumulative time (including nested imports) and self time (excluding\n\
78 nested imports). Note that its output may be broken in multi-threaded\n\
79 application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
80 -X dev: enable CPythons development mode”, introducing additional runtime\n\
81 checks which are too expensive to be enabled by default. Effect of the\n\
82 developer mode:\n\
83 * Add default warning filter, as -W default\n\
84 * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\
85 * Enable the faulthandler module to dump the Python traceback on a crash\n\
86 * Enable asyncio debug mode\n\
87 * Set the dev_mode attribute of sys.flags to True\n\
88 * io.IOBase destructor logs close() exceptions\n\
89 -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\
90 locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\
91 otherwise activate automatically)\n\
92 -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
93 given directory instead of to the code tree\n\
94\n\
Victor Stinner95e2cbf2019-03-01 16:25:19 +010095--check-hash-based-pycs always|default|never:\n\
96 control how Python invalidates hash-based .pyc files\n\
97";
98static const char usage_4[] = "\
99file : program read from script file\n\
100- : program read from stdin (default; interactive mode if a tty)\n\
101arg ...: arguments passed to program in sys.argv[1:]\n\n\
102Other environment variables:\n\
103PYTHONSTARTUP: file executed on interactive startup (no default)\n\
104PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
105 default module search path. The result is sys.path.\n\
106";
107static const char usage_5[] =
108"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
109" The default module search path uses %s.\n"
110"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
Inada Naoki95826c72019-12-14 14:27:32 +0900111"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100112"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
113"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
114static const char usage_6[] =
115"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Serhiy Storchakae9c90aa2019-08-24 12:49:27 +0300116" to seed the hashes of str and bytes objects. It can also be set to an\n"
117" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100118" predictable seed.\n"
119"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
120" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
121" hooks.\n"
122"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
123" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
124" locale coercion and locale compatibility warnings on stderr.\n"
125"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
126" debugger. It can be set to the callable of your debugger of choice.\n"
127"PYTHONDEVMODE: enable the development mode.\n"
128"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
129
130#if defined(MS_WINDOWS)
131# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
132#else
133# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
134#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200135
136
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100137/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200138
Victor Stinner6c785c02018-08-01 17:56:14 +0200139/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200140 stdin and stdout error handler to "surrogateescape". */
141int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200142int Py_DebugFlag = 0; /* Needed by parser.c */
143int Py_VerboseFlag = 0; /* Needed by import.c */
144int Py_QuietFlag = 0; /* Needed by sysmodule.c */
145int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
146int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
147int Py_OptimizeFlag = 0; /* Needed by compile.c */
148int Py_NoSiteFlag = 0; /* Suppress 'import site' */
149int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
150int Py_FrozenFlag = 0; /* Needed by getpath.c */
151int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
152int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
153int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
154int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
155int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
156int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
157#ifdef MS_WINDOWS
158int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
159int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
160#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200161
162
Victor Stinner1075d162019-03-25 23:19:57 +0100163static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100164_Py_GetGlobalVariablesAsDict(void)
165{
166 PyObject *dict, *obj;
167
168 dict = PyDict_New();
169 if (dict == NULL) {
170 return NULL;
171 }
172
173#define SET_ITEM(KEY, EXPR) \
174 do { \
175 obj = (EXPR); \
176 if (obj == NULL) { \
177 return NULL; \
178 } \
179 int res = PyDict_SetItemString(dict, (KEY), obj); \
180 Py_DECREF(obj); \
181 if (res < 0) { \
182 goto fail; \
183 } \
184 } while (0)
185#define SET_ITEM_INT(VAR) \
186 SET_ITEM(#VAR, PyLong_FromLong(VAR))
187#define FROM_STRING(STR) \
188 ((STR != NULL) ? \
189 PyUnicode_FromString(STR) \
190 : (Py_INCREF(Py_None), Py_None))
191#define SET_ITEM_STR(VAR) \
192 SET_ITEM(#VAR, FROM_STRING(VAR))
193
194 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
195 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
196 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
197 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
198
199 SET_ITEM_INT(Py_UTF8Mode);
200 SET_ITEM_INT(Py_DebugFlag);
201 SET_ITEM_INT(Py_VerboseFlag);
202 SET_ITEM_INT(Py_QuietFlag);
203 SET_ITEM_INT(Py_InteractiveFlag);
204 SET_ITEM_INT(Py_InspectFlag);
205
206 SET_ITEM_INT(Py_OptimizeFlag);
207 SET_ITEM_INT(Py_NoSiteFlag);
208 SET_ITEM_INT(Py_BytesWarningFlag);
209 SET_ITEM_INT(Py_FrozenFlag);
210 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
211 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
212 SET_ITEM_INT(Py_NoUserSiteDirectory);
213 SET_ITEM_INT(Py_UnbufferedStdioFlag);
214 SET_ITEM_INT(Py_HashRandomizationFlag);
215 SET_ITEM_INT(Py_IsolatedFlag);
216
217#ifdef MS_WINDOWS
218 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
219 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
220#endif
221
222 return dict;
223
224fail:
225 Py_DECREF(dict);
226 return NULL;
227
228#undef FROM_STRING
229#undef SET_ITEM
230#undef SET_ITEM_INT
231#undef SET_ITEM_STR
232}
233
234
Victor Stinner331a6a52019-05-27 16:39:22 +0200235/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200236
Victor Stinner331a6a52019-05-27 16:39:22 +0200237PyStatus PyStatus_Ok(void)
238{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200239
Victor Stinner331a6a52019-05-27 16:39:22 +0200240PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200241{
Victor Stinner331a6a52019-05-27 16:39:22 +0200242 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner871ff772019-05-17 23:54:00 +0200243 .err_msg = err_msg};
244}
245
Victor Stinner331a6a52019-05-27 16:39:22 +0200246PyStatus PyStatus_NoMemory(void)
247{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200248
Victor Stinner331a6a52019-05-27 16:39:22 +0200249PyStatus PyStatus_Exit(int exitcode)
250{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200251
252
Victor Stinner331a6a52019-05-27 16:39:22 +0200253int PyStatus_IsError(PyStatus status)
254{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200255
Victor Stinner331a6a52019-05-27 16:39:22 +0200256int PyStatus_IsExit(PyStatus status)
257{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200258
Victor Stinner331a6a52019-05-27 16:39:22 +0200259int PyStatus_Exception(PyStatus status)
260{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200261
262
Victor Stinner331a6a52019-05-27 16:39:22 +0200263/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100264
265#ifndef NDEBUG
266int
Victor Stinner331a6a52019-05-27 16:39:22 +0200267_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100268{
269 assert(list->length >= 0);
270 if (list->length != 0) {
271 assert(list->items != NULL);
272 }
273 for (Py_ssize_t i = 0; i < list->length; i++) {
274 assert(list->items[i] != NULL);
275 }
276 return 1;
277}
278#endif /* Py_DEBUG */
279
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100280
Victor Stinner6c785c02018-08-01 17:56:14 +0200281void
Victor Stinner331a6a52019-05-27 16:39:22 +0200282_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200283{
Victor Stinner331a6a52019-05-27 16:39:22 +0200284 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100285 for (Py_ssize_t i=0; i < list->length; i++) {
286 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200287 }
Victor Stinner74f65682019-03-15 15:08:05 +0100288 PyMem_RawFree(list->items);
289 list->length = 0;
290 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200291}
292
293
Victor Stinner74f65682019-03-15 15:08:05 +0100294int
Victor Stinner331a6a52019-05-27 16:39:22 +0200295_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200296{
Victor Stinner331a6a52019-05-27 16:39:22 +0200297 assert(_PyWideStringList_CheckConsistency(list));
298 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100299
300 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200301 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100302 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300303 }
Victor Stinner74f65682019-03-15 15:08:05 +0100304
Victor Stinnerfb4ae152019-09-30 01:40:17 +0200305 PyWideStringList copy = _PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100306
307 size_t size = list2->length * sizeof(list2->items[0]);
308 copy.items = PyMem_RawMalloc(size);
309 if (copy.items == NULL) {
310 return -1;
311 }
312
313 for (Py_ssize_t i=0; i < list2->length; i++) {
314 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
315 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200316 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100317 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200318 }
Victor Stinner74f65682019-03-15 15:08:05 +0100319 copy.items[i] = item;
320 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200321 }
Victor Stinner74f65682019-03-15 15:08:05 +0100322
Victor Stinner331a6a52019-05-27 16:39:22 +0200323 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100324 *list = copy;
325 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200326}
327
328
Victor Stinner331a6a52019-05-27 16:39:22 +0200329PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100330PyWideStringList_Insert(PyWideStringList *list,
331 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100332{
Victor Stinner3842f292019-08-23 16:57:54 +0100333 Py_ssize_t len = list->length;
334 if (len == PY_SSIZE_T_MAX) {
Min ho Kim96e12d52019-07-22 06:12:33 +1000335 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200336 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100337 }
Victor Stinner3842f292019-08-23 16:57:54 +0100338 if (index < 0) {
339 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
340 }
341 if (index > len) {
342 index = len;
343 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100344
Victor Stinner74f65682019-03-15 15:08:05 +0100345 wchar_t *item2 = _PyMem_RawWcsdup(item);
346 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200347 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100348 }
Victor Stinner74f65682019-03-15 15:08:05 +0100349
Victor Stinner3842f292019-08-23 16:57:54 +0100350 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100351 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
352 if (items2 == NULL) {
353 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200354 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100355 }
356
Victor Stinner3842f292019-08-23 16:57:54 +0100357 if (index < len) {
358 memmove(&items2[index + 1],
359 &items2[index],
360 (len - index) * sizeof(items2[0]));
361 }
362
363 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100364 list->items = items2;
365 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200366 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100367}
368
369
Victor Stinner331a6a52019-05-27 16:39:22 +0200370PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100371PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
372{
373 return PyWideStringList_Insert(list, list->length, item);
374}
375
376
377PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200378_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100379{
380 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200381 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
382 if (_PyStatus_EXCEPTION(status)) {
383 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100384 }
385 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200386 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100387}
388
389
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100390static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200391_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100392{
393 for (Py_ssize_t i = 0; i < list->length; i++) {
394 if (wcscmp(list->items[i], item) == 0) {
395 return 1;
396 }
397 }
398 return 0;
399}
400
401
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100402PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200403_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100404{
Victor Stinner331a6a52019-05-27 16:39:22 +0200405 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100406
Victor Stinner74f65682019-03-15 15:08:05 +0100407 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100408 if (pylist == NULL) {
409 return NULL;
410 }
411
Victor Stinner74f65682019-03-15 15:08:05 +0100412 for (Py_ssize_t i = 0; i < list->length; i++) {
413 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
414 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100415 Py_DECREF(pylist);
416 return NULL;
417 }
Victor Stinner74f65682019-03-15 15:08:05 +0100418 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100419 }
420 return pylist;
421}
422
423
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100424/* --- Py_SetStandardStreamEncoding() ----------------------------- */
425
Victor Stinner124b9eb2018-08-29 01:29:06 +0200426/* Helper to allow an embedding application to override the normal
427 * mechanism that attempts to figure out an appropriate IO encoding
428 */
429
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200430static char *_Py_StandardStreamEncoding = NULL;
431static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200432
433int
434Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
435{
436 if (Py_IsInitialized()) {
437 /* This is too late to have any effect */
438 return -1;
439 }
440
441 int res = 0;
442
443 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
444 but Py_Initialize() can change the allocator. Use a known allocator
445 to be able to release the memory later. */
446 PyMemAllocatorEx old_alloc;
447 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
448
449 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
450 * initialised yet.
451 *
452 * However, the raw memory allocators are initialised appropriately
453 * as C static variables, so _PyMem_RawStrdup is OK even though
454 * Py_Initialize hasn't been called yet.
455 */
456 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200457 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200458 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
459 if (!_Py_StandardStreamEncoding) {
460 res = -2;
461 goto done;
462 }
463 }
464 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200465 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200466 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
467 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200468 PyMem_RawFree(_Py_StandardStreamEncoding);
469 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200470 res = -3;
471 goto done;
472 }
473 }
474#ifdef MS_WINDOWS
475 if (_Py_StandardStreamEncoding) {
476 /* Overriding the stream encoding implies legacy streams */
477 Py_LegacyWindowsStdioFlag = 1;
478 }
479#endif
480
481done:
482 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
483
484 return res;
485}
486
487
488void
489_Py_ClearStandardStreamEncoding(void)
490{
491 /* Use the same allocator than Py_SetStandardStreamEncoding() */
492 PyMemAllocatorEx old_alloc;
493 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
494
495 /* We won't need them anymore. */
496 if (_Py_StandardStreamEncoding) {
497 PyMem_RawFree(_Py_StandardStreamEncoding);
498 _Py_StandardStreamEncoding = NULL;
499 }
500 if (_Py_StandardStreamErrors) {
501 PyMem_RawFree(_Py_StandardStreamErrors);
502 _Py_StandardStreamErrors = NULL;
503 }
504
505 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
506}
507
508
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100509/* --- Py_GetArgcArgv() ------------------------------------------- */
510
511/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200512static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100513
514
515void
516_Py_ClearArgcArgv(void)
517{
518 PyMemAllocatorEx old_alloc;
519 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
520
Victor Stinner331a6a52019-05-27 16:39:22 +0200521 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100522
523 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
524}
525
526
Victor Stinner4fffd382019-03-06 01:44:31 +0100527static int
Victor Stinner74f65682019-03-15 15:08:05 +0100528_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100529{
Victor Stinner331a6a52019-05-27 16:39:22 +0200530 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100531 int res;
532
533 PyMemAllocatorEx old_alloc;
534 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
535
Victor Stinner331a6a52019-05-27 16:39:22 +0200536 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100537
538 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
539 return res;
540}
541
542
543/* Make the *original* argc/argv available to other modules.
544 This is rare, but it is needed by the secureware extension. */
545void
546Py_GetArgcArgv(int *argc, wchar_t ***argv)
547{
Victor Stinner74f65682019-03-15 15:08:05 +0100548 *argc = (int)orig_argv.length;
549 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100550}
551
552
Victor Stinner331a6a52019-05-27 16:39:22 +0200553/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100554
555#define DECODE_LOCALE_ERR(NAME, LEN) \
556 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200557 ? _PyStatus_ERR("cannot decode " NAME) \
558 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100559
Victor Stinner441b10c2019-09-28 04:28:35 +0200560
Victor Stinner6c785c02018-08-01 17:56:14 +0200561/* Free memory allocated in config, but don't clear all attributes */
562void
Victor Stinner331a6a52019-05-27 16:39:22 +0200563PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200564{
565#define CLEAR(ATTR) \
566 do { \
567 PyMem_RawFree(ATTR); \
568 ATTR = NULL; \
569 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200570
571 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200572 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200573 CLEAR(config->home);
574 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200575
Victor Stinner331a6a52019-05-27 16:39:22 +0200576 _PyWideStringList_Clear(&config->argv);
577 _PyWideStringList_Clear(&config->warnoptions);
578 _PyWideStringList_Clear(&config->xoptions);
579 _PyWideStringList_Clear(&config->module_search_paths);
580 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200581
582 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700583 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200584 CLEAR(config->prefix);
585 CLEAR(config->base_prefix);
586 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200587 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200588
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200589 CLEAR(config->filesystem_encoding);
590 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200591 CLEAR(config->stdio_encoding);
592 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100593 CLEAR(config->run_command);
594 CLEAR(config->run_module);
595 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400596 CLEAR(config->check_hash_pycs_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200597#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200598}
599
600
Victor Stinner8462a492019-10-01 12:06:16 +0200601void
Victor Stinner331a6a52019-05-27 16:39:22 +0200602_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200603{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200604 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200605
Victor Stinner022be022019-05-22 23:58:50 +0200606 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200607 config->isolated = -1;
608 config->use_environment = -1;
609 config->dev_mode = -1;
610 config->install_signal_handlers = 1;
611 config->use_hash_seed = -1;
612 config->faulthandler = -1;
613 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200614 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200615 config->parse_argv = 0;
616 config->site_import = -1;
617 config->bytes_warning = -1;
618 config->inspect = -1;
619 config->interactive = -1;
620 config->optimization_level = -1;
621 config->parser_debug= -1;
622 config->write_bytecode = -1;
623 config->verbose = -1;
624 config->quiet = -1;
625 config->user_site_directory = -1;
626 config->configure_c_stdio = 0;
627 config->buffered_stdio = -1;
628 config->_install_importlib = 1;
629 config->check_hash_pycs_mode = NULL;
630 config->pathconfig_warnings = -1;
631 config->_init_main = 1;
632#ifdef MS_WINDOWS
633 config->legacy_windows_stdio = -1;
634#endif
635}
636
637
Victor Stinner8462a492019-10-01 12:06:16 +0200638static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200639config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200640{
Victor Stinner8462a492019-10-01 12:06:16 +0200641 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200642
643 config->isolated = 0;
644 config->use_environment = 1;
645 config->site_import = 1;
646 config->bytes_warning = 0;
647 config->inspect = 0;
648 config->interactive = 0;
649 config->optimization_level = 0;
650 config->parser_debug= 0;
651 config->write_bytecode = 1;
652 config->verbose = 0;
653 config->quiet = 0;
654 config->user_site_directory = 1;
655 config->buffered_stdio = 1;
656 config->pathconfig_warnings = 1;
657#ifdef MS_WINDOWS
658 config->legacy_windows_stdio = 0;
659#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200660}
661
662
Victor Stinner8462a492019-10-01 12:06:16 +0200663void
Victor Stinner331a6a52019-05-27 16:39:22 +0200664PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200665{
Victor Stinner8462a492019-10-01 12:06:16 +0200666 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200667
Victor Stinner022be022019-05-22 23:58:50 +0200668 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200669 config->configure_c_stdio = 1;
670 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200671}
672
673
Victor Stinner8462a492019-10-01 12:06:16 +0200674void
Victor Stinner331a6a52019-05-27 16:39:22 +0200675PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200676{
Victor Stinner8462a492019-10-01 12:06:16 +0200677 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200678
Victor Stinner022be022019-05-22 23:58:50 +0200679 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200680 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200681 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200682 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200683 config->dev_mode = 0;
684 config->install_signal_handlers = 0;
685 config->use_hash_seed = 0;
686 config->faulthandler = 0;
687 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200688 config->pathconfig_warnings = 0;
689#ifdef MS_WINDOWS
690 config->legacy_windows_stdio = 0;
691#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200692}
693
694
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200695/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200696PyStatus
697PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200698{
Victor Stinner331a6a52019-05-27 16:39:22 +0200699 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
700 if (_PyStatus_EXCEPTION(status)) {
701 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200702 }
703
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200704 wchar_t *str2;
705 if (str != NULL) {
706 str2 = _PyMem_RawWcsdup(str);
707 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200708 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200709 }
710 }
711 else {
712 str2 = NULL;
713 }
714 PyMem_RawFree(*config_str);
715 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200716 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200717}
718
719
Victor Stinner331a6a52019-05-27 16:39:22 +0200720static PyStatus
721config_set_bytes_string(PyConfig *config, wchar_t **config_str,
722 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200723{
Victor Stinner331a6a52019-05-27 16:39:22 +0200724 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
725 if (_PyStatus_EXCEPTION(status)) {
726 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400727 }
728
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200729 wchar_t *str2;
730 if (str != NULL) {
731 size_t len;
732 str2 = Py_DecodeLocale(str, &len);
733 if (str2 == NULL) {
734 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200735 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200736 }
737 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200738 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200739 }
740 }
741 }
742 else {
743 str2 = NULL;
744 }
745 PyMem_RawFree(*config_str);
746 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200747 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200748}
749
750
Victor Stinner331a6a52019-05-27 16:39:22 +0200751#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
752 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400753
754
Victor Stinner70005ac2019-05-02 15:25:34 -0400755/* Decode str using Py_DecodeLocale() and set the result into *config_str.
756 Pre-initialize Python if needed to ensure that encodings are properly
757 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200758PyStatus
759PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200760 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400761{
Victor Stinner331a6a52019-05-27 16:39:22 +0200762 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400763}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200764
765
Victor Stinner331a6a52019-05-27 16:39:22 +0200766PyStatus
767_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200768{
Victor Stinner331a6a52019-05-27 16:39:22 +0200769 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200770
Victor Stinner331a6a52019-05-27 16:39:22 +0200771 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200772
773#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200774#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200775 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200776 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
777 if (_PyStatus_EXCEPTION(status)) { \
778 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200779 } \
780 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100781#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200782 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200783 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200784 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200785 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200786 } while (0)
787
Victor Stinner6d1c4672019-05-20 11:02:00 +0200788 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100789 COPY_ATTR(isolated);
790 COPY_ATTR(use_environment);
791 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200792 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200793 COPY_ATTR(use_hash_seed);
794 COPY_ATTR(hash_seed);
795 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200796 COPY_ATTR(faulthandler);
797 COPY_ATTR(tracemalloc);
798 COPY_ATTR(import_time);
799 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200800 COPY_ATTR(dump_refs);
801 COPY_ATTR(malloc_stats);
802
Victor Stinner124b9eb2018-08-29 01:29:06 +0200803 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200804 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200805 COPY_WSTR_ATTR(home);
806 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200807
Victor Stinnerae239f62019-05-16 17:02:56 +0200808 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100809 COPY_WSTRLIST(argv);
810 COPY_WSTRLIST(warnoptions);
811 COPY_WSTRLIST(xoptions);
812 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200813 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200814
Victor Stinner124b9eb2018-08-29 01:29:06 +0200815 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700816 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200817 COPY_WSTR_ATTR(prefix);
818 COPY_WSTR_ATTR(base_prefix);
819 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200820 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200821
Victor Stinner6c785c02018-08-01 17:56:14 +0200822 COPY_ATTR(site_import);
823 COPY_ATTR(bytes_warning);
824 COPY_ATTR(inspect);
825 COPY_ATTR(interactive);
826 COPY_ATTR(optimization_level);
827 COPY_ATTR(parser_debug);
828 COPY_ATTR(write_bytecode);
829 COPY_ATTR(verbose);
830 COPY_ATTR(quiet);
831 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200832 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200833 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400834 COPY_WSTR_ATTR(filesystem_encoding);
835 COPY_WSTR_ATTR(filesystem_errors);
836 COPY_WSTR_ATTR(stdio_encoding);
837 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200838#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200839 COPY_ATTR(legacy_windows_stdio);
840#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100841 COPY_ATTR(skip_source_first_line);
842 COPY_WSTR_ATTR(run_command);
843 COPY_WSTR_ATTR(run_module);
844 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400845 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200846 COPY_ATTR(pathconfig_warnings);
847 COPY_ATTR(_init_main);
Victor Stinner6c785c02018-08-01 17:56:14 +0200848
849#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200850#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200851#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200852 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200853}
854
855
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100856static PyObject *
Victor Stinner331a6a52019-05-27 16:39:22 +0200857config_as_dict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100858{
859 PyObject *dict;
860
861 dict = PyDict_New();
862 if (dict == NULL) {
863 return NULL;
864 }
865
866#define SET_ITEM(KEY, EXPR) \
867 do { \
868 PyObject *obj = (EXPR); \
869 if (obj == NULL) { \
870 goto fail; \
871 } \
872 int res = PyDict_SetItemString(dict, (KEY), obj); \
873 Py_DECREF(obj); \
874 if (res < 0) { \
875 goto fail; \
876 } \
877 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100878#define SET_ITEM_INT(ATTR) \
879 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
880#define SET_ITEM_UINT(ATTR) \
881 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100882#define FROM_WSTRING(STR) \
883 ((STR != NULL) ? \
884 PyUnicode_FromWideChar(STR, -1) \
885 : (Py_INCREF(Py_None), Py_None))
886#define SET_ITEM_WSTR(ATTR) \
887 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
888#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200889 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100890
Victor Stinner6d1c4672019-05-20 11:02:00 +0200891 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100892 SET_ITEM_INT(isolated);
893 SET_ITEM_INT(use_environment);
894 SET_ITEM_INT(dev_mode);
895 SET_ITEM_INT(install_signal_handlers);
896 SET_ITEM_INT(use_hash_seed);
897 SET_ITEM_UINT(hash_seed);
898 SET_ITEM_INT(faulthandler);
899 SET_ITEM_INT(tracemalloc);
900 SET_ITEM_INT(import_time);
901 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100902 SET_ITEM_INT(dump_refs);
903 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400904 SET_ITEM_WSTR(filesystem_encoding);
905 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100906 SET_ITEM_WSTR(pycache_prefix);
907 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200908 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100909 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100910 SET_ITEM_WSTRLIST(xoptions);
911 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200912 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100913 SET_ITEM_WSTR(home);
914 SET_ITEM_WSTRLIST(module_search_paths);
915 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700916 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100917 SET_ITEM_WSTR(prefix);
918 SET_ITEM_WSTR(base_prefix);
919 SET_ITEM_WSTR(exec_prefix);
920 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100921 SET_ITEM_INT(site_import);
922 SET_ITEM_INT(bytes_warning);
923 SET_ITEM_INT(inspect);
924 SET_ITEM_INT(interactive);
925 SET_ITEM_INT(optimization_level);
926 SET_ITEM_INT(parser_debug);
927 SET_ITEM_INT(write_bytecode);
928 SET_ITEM_INT(verbose);
929 SET_ITEM_INT(quiet);
930 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200931 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100932 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400933 SET_ITEM_WSTR(stdio_encoding);
934 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100935#ifdef MS_WINDOWS
936 SET_ITEM_INT(legacy_windows_stdio);
937#endif
938 SET_ITEM_INT(skip_source_first_line);
939 SET_ITEM_WSTR(run_command);
940 SET_ITEM_WSTR(run_module);
941 SET_ITEM_WSTR(run_filename);
942 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400943 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200944 SET_ITEM_INT(pathconfig_warnings);
945 SET_ITEM_INT(_init_main);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100946
947 return dict;
948
949fail:
950 Py_DECREF(dict);
951 return NULL;
952
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100953#undef FROM_WSTRING
954#undef SET_ITEM
955#undef SET_ITEM_INT
956#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100957#undef SET_ITEM_WSTR
958#undef SET_ITEM_WSTRLIST
959}
960
961
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100962static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +0200963config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +0200964{
Victor Stinner20004952019-03-26 02:31:11 +0100965 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200966}
967
968
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100969/* Get a copy of the environment variable as wchar_t*.
970 Return 0 on success, but *dest can be NULL.
971 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200972static PyStatus
973config_get_env_dup(PyConfig *config,
974 wchar_t **dest,
975 wchar_t *wname, char *name,
976 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200977{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200978 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100979 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200980
Victor Stinner20004952019-03-26 02:31:11 +0100981 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200982 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200983 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200984 }
985
986#ifdef MS_WINDOWS
987 const wchar_t *var = _wgetenv(wname);
988 if (!var || var[0] == '\0') {
989 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200990 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200991 }
992
Victor Stinner331a6a52019-05-27 16:39:22 +0200993 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +0200994#else
995 const char *var = getenv(name);
996 if (!var || var[0] == '\0') {
997 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +0200998 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200999 }
1000
Victor Stinner331a6a52019-05-27 16:39:22 +02001001 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001002#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001003}
1004
1005
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001006#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001007 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001008
1009
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001010static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001011config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001012{
Victor Stinner022be022019-05-22 23:58:50 +02001013 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1014 /* Python and Isolated configuration ignore global variables */
1015 return;
1016 }
1017
Victor Stinner6c785c02018-08-01 17:56:14 +02001018#define COPY_FLAG(ATTR, VALUE) \
1019 if (config->ATTR == -1) { \
1020 config->ATTR = VALUE; \
1021 }
1022#define COPY_NOT_FLAG(ATTR, VALUE) \
1023 if (config->ATTR == -1) { \
1024 config->ATTR = !(VALUE); \
1025 }
1026
Victor Stinner20004952019-03-26 02:31:11 +01001027 COPY_FLAG(isolated, Py_IsolatedFlag);
1028 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001029 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1030 COPY_FLAG(inspect, Py_InspectFlag);
1031 COPY_FLAG(interactive, Py_InteractiveFlag);
1032 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1033 COPY_FLAG(parser_debug, Py_DebugFlag);
1034 COPY_FLAG(verbose, Py_VerboseFlag);
1035 COPY_FLAG(quiet, Py_QuietFlag);
1036#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001037 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1038#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001039 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001040
Victor Stinner6c785c02018-08-01 17:56:14 +02001041 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1042 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1043 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1044 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1045
Victor Stinner6c785c02018-08-01 17:56:14 +02001046#undef COPY_FLAG
1047#undef COPY_NOT_FLAG
1048}
1049
1050
1051/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001052static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001053config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001054{
1055#define COPY_FLAG(ATTR, VAR) \
1056 if (config->ATTR != -1) { \
1057 VAR = config->ATTR; \
1058 }
1059#define COPY_NOT_FLAG(ATTR, VAR) \
1060 if (config->ATTR != -1) { \
1061 VAR = !config->ATTR; \
1062 }
1063
Victor Stinner20004952019-03-26 02:31:11 +01001064 COPY_FLAG(isolated, Py_IsolatedFlag);
1065 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001066 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1067 COPY_FLAG(inspect, Py_InspectFlag);
1068 COPY_FLAG(interactive, Py_InteractiveFlag);
1069 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1070 COPY_FLAG(parser_debug, Py_DebugFlag);
1071 COPY_FLAG(verbose, Py_VerboseFlag);
1072 COPY_FLAG(quiet, Py_QuietFlag);
1073#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001074 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1075#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001076 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001077
Victor Stinner6c785c02018-08-01 17:56:14 +02001078 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1079 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1080 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1081 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1082
Victor Stinner6c785c02018-08-01 17:56:14 +02001083 /* Random or non-zero hash seed */
1084 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1085 config->hash_seed != 0);
1086
1087#undef COPY_FLAG
1088#undef COPY_NOT_FLAG
1089}
1090
1091
1092/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1093 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001094static PyStatus
1095config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001096{
Victor Stinner331a6a52019-05-27 16:39:22 +02001097 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001098
Victor Stinner6c785c02018-08-01 17:56:14 +02001099 /* If Py_SetProgramName() was called, use its value */
1100 const wchar_t *program_name = _Py_path_config.program_name;
1101 if (program_name != NULL) {
1102 config->program_name = _PyMem_RawWcsdup(program_name);
1103 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001104 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001105 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001106 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001107 }
1108
1109#ifdef __APPLE__
1110 /* On MacOS X, when the Python interpreter is embedded in an
1111 application bundle, it gets executed by a bootstrapping script
1112 that does os.execve() with an argv[0] that's different from the
1113 actual Python executable. This is needed to keep the Finder happy,
1114 or rather, to work around Apple's overly strict requirements of
1115 the process name. However, we still need a usable sys.executable,
1116 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001117 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001118 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001119 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001120 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001121 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1122 "PYTHONEXECUTABLE environment variable");
1123 if (_PyStatus_EXCEPTION(status)) {
1124 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001125 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001126 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001127 }
1128#ifdef WITH_NEXT_FRAMEWORK
1129 else {
1130 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1131 if (pyvenv_launcher && *pyvenv_launcher) {
1132 /* Used by Mac/Tools/pythonw.c to forward
1133 * the argv0 of the stub executable
1134 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001135 status = CONFIG_SET_BYTES_STR(config,
1136 &config->program_name,
1137 pyvenv_launcher,
1138 "__PYVENV_LAUNCHER__ environment variable");
1139 if (_PyStatus_EXCEPTION(status)) {
1140 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001141 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001142
1143 /*
1144 * This environment variable is used to communicate between
1145 * the stub launcher and the real interpreter and isn't needed
1146 * beyond this point.
1147 *
1148 * Clean up to avoid problems when launching other programs
1149 * later on.
1150 */
1151 (void)unsetenv("__PYVENV_LAUNCHER__");
1152
Victor Stinner331a6a52019-05-27 16:39:22 +02001153 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001154 }
1155 }
1156#endif /* WITH_NEXT_FRAMEWORK */
1157#endif /* __APPLE__ */
1158
Victor Stinnerfed02e12019-05-17 11:12:09 +02001159 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001160 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001161 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1162 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1163 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001164 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001165 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001166 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001167 }
1168
Victor Stinnerfed02e12019-05-17 11:12:09 +02001169 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001170#ifdef MS_WINDOWS
1171 const wchar_t *default_program_name = L"python";
1172#else
1173 const wchar_t *default_program_name = L"python3";
1174#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001175 status = PyConfig_SetString(config, &config->program_name,
1176 default_program_name);
1177 if (_PyStatus_EXCEPTION(status)) {
1178 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001179 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001180 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001181}
1182
Victor Stinner331a6a52019-05-27 16:39:22 +02001183static PyStatus
1184config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001185{
1186 assert(config->executable == NULL);
1187
1188 /* If Py_SetProgramFullPath() was called, use its value */
1189 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1190 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001191 PyStatus status = PyConfig_SetString(config,
1192 &config->executable,
1193 program_full_path);
1194 if (_PyStatus_EXCEPTION(status)) {
1195 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001196 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001197 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001198 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001199 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001200}
Victor Stinner6c785c02018-08-01 17:56:14 +02001201
Victor Stinner4fffd382019-03-06 01:44:31 +01001202
Victor Stinner6c785c02018-08-01 17:56:14 +02001203static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001204config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001205{
Victor Stinner74f65682019-03-15 15:08:05 +01001206 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001207}
1208
1209
Victor Stinner331a6a52019-05-27 16:39:22 +02001210static PyStatus
1211config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001212{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001213 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001214
1215 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001216 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001217 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001218 PyStatus status = PyConfig_SetString(config, &config->home, home);
1219 if (_PyStatus_EXCEPTION(status)) {
1220 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001221 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001222 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001223 }
1224
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001225 return CONFIG_GET_ENV_DUP(config, &config->home,
1226 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001227}
1228
1229
Victor Stinner331a6a52019-05-27 16:39:22 +02001230static PyStatus
1231config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001232{
Victor Stinner331a6a52019-05-27 16:39:22 +02001233 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001234
1235 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1236 /* Convert a text seed to a numeric one */
1237 if (seed_text && strcmp(seed_text, "random") != 0) {
1238 const char *endptr = seed_text;
1239 unsigned long seed;
1240 errno = 0;
1241 seed = strtoul(seed_text, (char **)&endptr, 10);
1242 if (*endptr != '\0'
1243 || seed > 4294967295UL
1244 || (errno == ERANGE && seed == ULONG_MAX))
1245 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001246 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001247 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001248 }
1249 /* Use a specific hash */
1250 config->use_hash_seed = 1;
1251 config->hash_seed = seed;
1252 }
1253 else {
1254 /* Use a random hash */
1255 config->use_hash_seed = 0;
1256 config->hash_seed = 0;
1257 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001258 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001259}
1260
1261
Victor Stinner6c785c02018-08-01 17:56:14 +02001262static int
1263config_wstr_to_int(const wchar_t *wstr, int *result)
1264{
1265 const wchar_t *endptr = wstr;
1266 errno = 0;
1267 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1268 if (*endptr != '\0' || errno == ERANGE) {
1269 return -1;
1270 }
1271 if (value < INT_MIN || value > INT_MAX) {
1272 return -1;
1273 }
1274
1275 *result = (int)value;
1276 return 0;
1277}
1278
1279
Victor Stinner331a6a52019-05-27 16:39:22 +02001280static PyStatus
1281config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001282{
Victor Stinner331a6a52019-05-27 16:39:22 +02001283 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001284 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001285
Victor Stinner6c785c02018-08-01 17:56:14 +02001286 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001287 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1288 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1289 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1290 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001291
1292 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001293 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001294 if (dont_write_bytecode) {
1295 config->write_bytecode = 0;
1296 }
1297
1298 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001299 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001300 if (no_user_site_directory) {
1301 config->user_site_directory = 0;
1302 }
1303
1304 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001305 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001306 if (unbuffered_stdio) {
1307 config->buffered_stdio = 0;
1308 }
1309
1310#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001311 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001312 "PYTHONLEGACYWINDOWSSTDIO");
1313#endif
1314
Victor Stinner331a6a52019-05-27 16:39:22 +02001315 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001316 config->dump_refs = 1;
1317 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001318 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001319 config->malloc_stats = 1;
1320 }
1321
Victor Stinner331a6a52019-05-27 16:39:22 +02001322 if (config->pythonpath_env == NULL) {
1323 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1324 L"PYTHONPATH", "PYTHONPATH");
1325 if (_PyStatus_EXCEPTION(status)) {
1326 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001327 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001328 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001329
1330 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001331 status = config_init_hash_seed(config);
1332 if (_PyStatus_EXCEPTION(status)) {
1333 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001334 }
1335 }
1336
Victor Stinner331a6a52019-05-27 16:39:22 +02001337 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001338}
1339
1340
Victor Stinner331a6a52019-05-27 16:39:22 +02001341static PyStatus
1342config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001343{
1344 int nframe;
1345 int valid;
1346
Victor Stinner331a6a52019-05-27 16:39:22 +02001347 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001348 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001349 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001350 valid = (nframe >= 0);
1351 }
1352 else {
1353 valid = 0;
1354 }
1355 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001356 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001357 }
1358 config->tracemalloc = nframe;
1359 }
1360
1361 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1362 if (xoption) {
1363 const wchar_t *sep = wcschr(xoption, L'=');
1364 if (sep) {
1365 if (!config_wstr_to_int(sep + 1, &nframe)) {
1366 valid = (nframe >= 0);
1367 }
1368 else {
1369 valid = 0;
1370 }
1371 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001372 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1373 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001374 }
1375 }
1376 else {
1377 /* -X tracemalloc behaves as -X tracemalloc=1 */
1378 nframe = 1;
1379 }
1380 config->tracemalloc = nframe;
1381 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001382 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001383}
1384
1385
Victor Stinner331a6a52019-05-27 16:39:22 +02001386static PyStatus
1387config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001388{
1389 assert(config->pycache_prefix == NULL);
1390
1391 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1392 if (xoption) {
1393 const wchar_t *sep = wcschr(xoption, L'=');
1394 if (sep && wcslen(sep) > 1) {
1395 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1396 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001397 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001398 }
1399 }
1400 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001401 // PYTHONPYCACHEPREFIX env var ignored
1402 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001403 config->pycache_prefix = NULL;
1404 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001405 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001406 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001407
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001408 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1409 L"PYTHONPYCACHEPREFIX",
1410 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001411}
1412
1413
Victor Stinner331a6a52019-05-27 16:39:22 +02001414static PyStatus
1415config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001416{
1417 /* More complex options configured by env var and -X option */
1418 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001419 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001420 || config_get_xoption(config, L"faulthandler")) {
1421 config->faulthandler = 1;
1422 }
1423 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001424 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001425 || config_get_xoption(config, L"importtime")) {
1426 config->import_time = 1;
1427 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001428
Victor Stinner331a6a52019-05-27 16:39:22 +02001429 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001430 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001431 status = config_init_tracemalloc(config);
1432 if (_PyStatus_EXCEPTION(status)) {
1433 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001434 }
1435 }
1436
1437 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001438 status = config_init_pycache_prefix(config);
1439 if (_PyStatus_EXCEPTION(status)) {
1440 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001441 }
1442 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001443 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001444}
1445
1446
Victor Stinner709d23d2019-05-02 14:56:30 -04001447static const wchar_t *
Andy Lesteraa450a02020-03-07 11:36:04 -06001448config_get_stdio_errors(void)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001449{
1450#ifndef MS_WINDOWS
1451 const char *loc = setlocale(LC_CTYPE, NULL);
1452 if (loc != NULL) {
1453 /* surrogateescape is the default in the legacy C and POSIX locales */
1454 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001455 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001456 }
1457
1458#ifdef PY_COERCE_C_LOCALE
1459 /* surrogateescape is the default in locale coercion target locales */
1460 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001461 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001462 }
1463#endif
1464 }
1465
Victor Stinner709d23d2019-05-02 14:56:30 -04001466 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001467#else
1468 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001469 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001470#endif
1471}
1472
1473
Victor Stinner331a6a52019-05-27 16:39:22 +02001474static PyStatus
1475config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001476{
1477#ifdef MS_WINDOWS
1478 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001479 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001480 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001481#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001482 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001483#else
1484 const char *encoding = nl_langinfo(CODESET);
1485 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001486 return _PyStatus_ERR("failed to get the locale encoding: "
1487 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001488 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001489 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001490 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001491 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001492 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001493#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001494}
1495
1496
Victor Stinner331a6a52019-05-27 16:39:22 +02001497static PyStatus
1498config_init_stdio_encoding(PyConfig *config,
1499 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001500{
Victor Stinner331a6a52019-05-27 16:39:22 +02001501 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001502
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001503 /* If Py_SetStandardStreamEncoding() have been called, use these
1504 parameters. */
1505 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001506 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1507 _Py_StandardStreamEncoding,
1508 "_Py_StandardStreamEncoding");
1509 if (_PyStatus_EXCEPTION(status)) {
1510 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001511 }
1512 }
1513
1514 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001515 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1516 _Py_StandardStreamErrors,
1517 "_Py_StandardStreamErrors");
1518 if (_PyStatus_EXCEPTION(status)) {
1519 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001520 }
1521 }
1522
1523 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001524 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001525 }
1526
1527 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001528 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001529 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001530 char *pythonioencoding = _PyMem_RawStrdup(opt);
1531 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001532 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001533 }
1534
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001535 char *errors = strchr(pythonioencoding, ':');
1536 if (errors) {
1537 *errors = '\0';
1538 errors++;
1539 if (!errors[0]) {
1540 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001541 }
1542 }
1543
1544 /* Does PYTHONIOENCODING contain an encoding? */
1545 if (pythonioencoding[0]) {
1546 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001547 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1548 pythonioencoding,
1549 "PYTHONIOENCODING environment variable");
1550 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001551 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001552 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001553 }
1554 }
1555
1556 /* If the encoding is set but not the error handler,
1557 use "strict" error handler by default.
1558 PYTHONIOENCODING=latin1 behaves as
1559 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001560 if (!errors) {
1561 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001562 }
1563 }
1564
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001565 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001566 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1567 errors,
1568 "PYTHONIOENCODING environment variable");
1569 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001570 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001571 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001572 }
1573 }
1574
1575 PyMem_RawFree(pythonioencoding);
1576 }
1577
1578 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001579 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001580 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001581 status = PyConfig_SetString(config, &config->stdio_encoding,
1582 L"utf-8");
1583 if (_PyStatus_EXCEPTION(status)) {
1584 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001585 }
1586 }
1587 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001588 status = PyConfig_SetString(config, &config->stdio_errors,
1589 L"surrogateescape");
1590 if (_PyStatus_EXCEPTION(status)) {
1591 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001592 }
1593 }
1594 }
1595
1596 /* Choose the default error handler based on the current locale. */
1597 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001598 status = config_get_locale_encoding(config, &config->stdio_encoding);
1599 if (_PyStatus_EXCEPTION(status)) {
1600 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001601 }
1602 }
1603 if (config->stdio_errors == NULL) {
Andy Lesteraa450a02020-03-07 11:36:04 -06001604 const wchar_t *errors = config_get_stdio_errors();
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001605 assert(errors != NULL);
1606
Victor Stinner331a6a52019-05-27 16:39:22 +02001607 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1608 if (_PyStatus_EXCEPTION(status)) {
1609 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001610 }
1611 }
1612
Victor Stinner331a6a52019-05-27 16:39:22 +02001613 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001614}
1615
1616
Victor Stinner331a6a52019-05-27 16:39:22 +02001617static PyStatus
1618config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001619{
Victor Stinner331a6a52019-05-27 16:39:22 +02001620 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001621
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001622 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001623#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001624 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001625#else
Victor Stinnere2510952019-05-02 11:28:57 -04001626
1627#ifdef MS_WINDOWS
1628 if (preconfig->legacy_windows_fs_encoding) {
1629 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001630 status = PyConfig_SetString(config, &config->filesystem_encoding,
1631 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001632 }
1633 else
1634#endif
Victor Stinner20004952019-03-26 02:31:11 +01001635 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001636 status = PyConfig_SetString(config, &config->filesystem_encoding,
1637 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001638 }
Victor Stinnere2510952019-05-02 11:28:57 -04001639#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001640 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001641 status = PyConfig_SetString(config, &config->filesystem_encoding,
1642 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001643 }
Victor Stinnere2510952019-05-02 11:28:57 -04001644#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001645 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001646#ifdef MS_WINDOWS
1647 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001648 status = PyConfig_SetString(config, &config->filesystem_encoding,
1649 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001650#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001651 status = config_get_locale_encoding(config,
1652 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001653#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001654 }
Victor Stinnere2510952019-05-02 11:28:57 -04001655#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001656
Victor Stinner331a6a52019-05-27 16:39:22 +02001657 if (_PyStatus_EXCEPTION(status)) {
1658 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001659 }
1660 }
1661
1662 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001663 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001664#ifdef MS_WINDOWS
1665 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001666 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001667 }
1668 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001669 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001670 }
1671#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001672 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001673#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001674 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1675 if (_PyStatus_EXCEPTION(status)) {
1676 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001677 }
1678 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001679 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001680}
1681
1682
Victor Stinner331a6a52019-05-27 16:39:22 +02001683static PyStatus
1684config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001685{
Victor Stinner331a6a52019-05-27 16:39:22 +02001686 PyStatus status;
1687 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001688
Victor Stinner20004952019-03-26 02:31:11 +01001689 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001690 status = config_read_env_vars(config);
1691 if (_PyStatus_EXCEPTION(status)) {
1692 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001693 }
1694 }
1695
1696 /* -X options */
1697 if (config_get_xoption(config, L"showrefcount")) {
1698 config->show_ref_count = 1;
1699 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001700
Victor Stinner331a6a52019-05-27 16:39:22 +02001701 status = config_read_complex_options(config);
1702 if (_PyStatus_EXCEPTION(status)) {
1703 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001704 }
1705
Victor Stinner6c785c02018-08-01 17:56:14 +02001706 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001707 status = config_init_home(config);
1708 if (_PyStatus_EXCEPTION(status)) {
1709 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001710 }
1711 }
1712
Steve Dower177a41a2018-11-17 20:41:48 -08001713 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001714 status = config_init_executable(config);
1715 if (_PyStatus_EXCEPTION(status)) {
1716 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001717 }
1718 }
1719
Victor Stinner6c785c02018-08-01 17:56:14 +02001720 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001721 status = _PyConfig_InitPathConfig(config);
1722 if (_PyStatus_EXCEPTION(status)) {
1723 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001724 }
1725 }
1726
1727 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001728 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001729 if (config->faulthandler < 0) {
1730 config->faulthandler = 1;
1731 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001732 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001733 if (config->faulthandler < 0) {
1734 config->faulthandler = 0;
1735 }
1736 if (config->tracemalloc < 0) {
1737 config->tracemalloc = 0;
1738 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001739 if (config->use_hash_seed < 0) {
1740 config->use_hash_seed = 0;
1741 config->hash_seed = 0;
1742 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001743
Victor Stinner70fead22018-08-29 13:45:34 +02001744 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001745 status = config_init_fs_encoding(config, preconfig);
1746 if (_PyStatus_EXCEPTION(status)) {
1747 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001748 }
1749 }
1750
Victor Stinner331a6a52019-05-27 16:39:22 +02001751 status = config_init_stdio_encoding(config, preconfig);
1752 if (_PyStatus_EXCEPTION(status)) {
1753 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001754 }
1755
Victor Stinner62599762019-03-15 16:03:23 +01001756 if (config->argv.length < 1) {
1757 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001758 status = PyWideStringList_Append(&config->argv, L"");
1759 if (_PyStatus_EXCEPTION(status)) {
1760 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001761 }
1762 }
Victor Stinner870b0352019-05-17 03:15:12 +02001763
1764 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001765 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1766 L"default");
1767 if (_PyStatus_EXCEPTION(status)) {
1768 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001769 }
1770 }
1771
1772 if (config->configure_c_stdio < 0) {
1773 config->configure_c_stdio = 1;
1774 }
1775
Victor Stinner331a6a52019-05-27 16:39:22 +02001776 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001777}
Victor Stinner5ed69952018-11-06 15:59:52 +01001778
1779
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001780static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001781config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001782{
1783#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1784 /* don't translate newlines (\r\n <=> \n) */
1785 _setmode(fileno(stdin), O_BINARY);
1786 _setmode(fileno(stdout), O_BINARY);
1787 _setmode(fileno(stderr), O_BINARY);
1788#endif
1789
1790 if (!config->buffered_stdio) {
1791#ifdef HAVE_SETVBUF
1792 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1793 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1794 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1795#else /* !HAVE_SETVBUF */
1796 setbuf(stdin, (char *)NULL);
1797 setbuf(stdout, (char *)NULL);
1798 setbuf(stderr, (char *)NULL);
1799#endif /* !HAVE_SETVBUF */
1800 }
1801 else if (config->interactive) {
1802#ifdef MS_WINDOWS
1803 /* Doesn't have to have line-buffered -- use unbuffered */
1804 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1805 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1806#else /* !MS_WINDOWS */
1807#ifdef HAVE_SETVBUF
1808 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1809 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1810#endif /* HAVE_SETVBUF */
1811#endif /* !MS_WINDOWS */
1812 /* Leave stderr alone - it should be unbuffered anyway. */
1813 }
1814}
1815
1816
1817/* Write the configuration:
1818
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001819 - set Py_xxx global configuration variables
1820 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001821void
Victor Stinner331a6a52019-05-27 16:39:22 +02001822_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001823{
Victor Stinner331a6a52019-05-27 16:39:22 +02001824 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001825
1826 if (config->configure_c_stdio) {
1827 config_init_stdio(config);
1828 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001829
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001830 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001831 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001832 preconfig->isolated = config->isolated;
1833 preconfig->use_environment = config->use_environment;
1834 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001835}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001836
1837
Victor Stinner331a6a52019-05-27 16:39:22 +02001838/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001839
1840static void
Victor Stinner2f549082019-03-29 15:13:46 +01001841config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001842{
Victor Stinner2f549082019-03-29 15:13:46 +01001843 FILE *f = error ? stderr : stdout;
1844
1845 fprintf(f, usage_line, program);
1846 if (error)
1847 fprintf(f, "Try `python -h' for more information.\n");
1848 else {
1849 fputs(usage_1, f);
1850 fputs(usage_2, f);
1851 fputs(usage_3, f);
1852 fprintf(f, usage_4, (wint_t)DELIM);
1853 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1854 fputs(usage_6, f);
1855 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001856}
1857
1858
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001859/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001860static PyStatus
1861config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001862 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001863{
Victor Stinner331a6a52019-05-27 16:39:22 +02001864 PyStatus status;
1865 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001866 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001867 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001868
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001869 _PyOS_ResetGetOpt();
1870 do {
1871 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001872 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001873 if (c == EOF) {
1874 break;
1875 }
1876
1877 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001878 if (config->run_command == NULL) {
1879 /* -c is the last option; following arguments
1880 that look like options are left for the
1881 command to interpret. */
1882 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1883 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1884 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001885 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001886 }
1887 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1888 command[len - 2] = '\n';
1889 command[len - 1] = 0;
1890 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001891 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001892 break;
1893 }
1894
1895 if (c == 'm') {
1896 /* -m is the last option; following arguments
1897 that look like options are left for the
1898 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001899 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001900 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1901 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001902 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001903 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001904 }
1905 break;
1906 }
1907
1908 switch (c) {
1909 case 0:
1910 // Handle long option.
1911 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001912 if (wcscmp(_PyOS_optarg, L"always") == 0
1913 || wcscmp(_PyOS_optarg, L"never") == 0
1914 || wcscmp(_PyOS_optarg, L"default") == 0)
1915 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001916 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1917 _PyOS_optarg);
1918 if (_PyStatus_EXCEPTION(status)) {
1919 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001920 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001921 } else {
1922 fprintf(stderr, "--check-hash-based-pycs must be one of "
1923 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001924 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001925 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001926 }
1927 break;
1928
1929 case 'b':
1930 config->bytes_warning++;
1931 break;
1932
1933 case 'd':
1934 config->parser_debug++;
1935 break;
1936
1937 case 'i':
1938 config->inspect++;
1939 config->interactive++;
1940 break;
1941
Victor Stinner6dcb5422019-03-05 02:44:12 +01001942 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001943 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001944 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001945 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001946 break;
1947
1948 /* case 'J': reserved for Jython */
1949
1950 case 'O':
1951 config->optimization_level++;
1952 break;
1953
1954 case 'B':
1955 config->write_bytecode = 0;
1956 break;
1957
1958 case 's':
1959 config->user_site_directory = 0;
1960 break;
1961
1962 case 'S':
1963 config->site_import = 0;
1964 break;
1965
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001966 case 't':
1967 /* ignored for backwards compatibility */
1968 break;
1969
1970 case 'u':
1971 config->buffered_stdio = 0;
1972 break;
1973
1974 case 'v':
1975 config->verbose++;
1976 break;
1977
1978 case 'x':
1979 config->skip_source_first_line = 1;
1980 break;
1981
1982 case 'h':
1983 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001984 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001985 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001986
1987 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01001988 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001989 break;
1990
1991 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02001992 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
1993 if (_PyStatus_EXCEPTION(status)) {
1994 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001995 }
1996 break;
1997
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001998 case 'q':
1999 config->quiet++;
2000 break;
2001
2002 case 'R':
2003 config->use_hash_seed = 0;
2004 break;
2005
2006 /* This space reserved for other options */
2007
2008 default:
2009 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002010 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002011 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002012 }
2013 } while (1);
2014
Victor Stinner2f549082019-03-29 15:13:46 +01002015 if (print_version) {
2016 printf("Python %s\n",
2017 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002018 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002019 }
2020
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002021 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002022 && _PyOS_optind < argv->length
2023 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002024 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002025 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002026 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002027 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002028 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002029 }
2030 }
2031
2032 if (config->run_command != NULL || config->run_module != NULL) {
2033 /* Backup _PyOS_optind */
2034 _PyOS_optind--;
2035 }
2036
Victor Stinnerae239f62019-05-16 17:02:56 +02002037 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002038
Victor Stinner331a6a52019-05-27 16:39:22 +02002039 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002040}
2041
2042
2043#ifdef MS_WINDOWS
2044# define WCSTOK wcstok_s
2045#else
2046# define WCSTOK wcstok
2047#endif
2048
2049/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002050static PyStatus
2051config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002052{
Victor Stinner331a6a52019-05-27 16:39:22 +02002053 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002054 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2055 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002056 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002057 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002058 if (_PyStatus_EXCEPTION(status)) {
2059 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002060 }
2061
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002062 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002063 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002064 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002065 }
2066
2067
2068 wchar_t *warning, *context = NULL;
2069 for (warning = WCSTOK(env, L",", &context);
2070 warning != NULL;
2071 warning = WCSTOK(NULL, L",", &context))
2072 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002073 status = PyWideStringList_Append(warnoptions, warning);
2074 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002075 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002076 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002077 }
2078 }
2079 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002080 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002081}
2082
2083
Victor Stinner331a6a52019-05-27 16:39:22 +02002084static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002085warnoptions_append(PyConfig *config, PyWideStringList *options,
2086 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002087{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002088 /* config_init_warnoptions() add existing config warnoptions at the end:
2089 ensure that the new option is not already present in this list to
2090 prevent change the options order whne config_init_warnoptions() is
2091 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002092 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002093 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002094 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002095 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002096 if (_PyWideStringList_Find(options, option)) {
2097 /* Already present: do nothing */
2098 return _PyStatus_OK();
2099 }
2100 return PyWideStringList_Append(options, option);
2101}
2102
2103
2104static PyStatus
2105warnoptions_extend(PyConfig *config, PyWideStringList *options,
2106 const PyWideStringList *options2)
2107{
2108 const Py_ssize_t len = options2->length;
2109 wchar_t *const *items = options2->items;
2110
2111 for (Py_ssize_t i = 0; i < len; i++) {
2112 PyStatus status = warnoptions_append(config, options, items[i]);
2113 if (_PyStatus_EXCEPTION(status)) {
2114 return status;
2115 }
2116 }
2117 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002118}
2119
2120
Victor Stinner331a6a52019-05-27 16:39:22 +02002121static PyStatus
2122config_init_warnoptions(PyConfig *config,
2123 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002124 const PyWideStringList *env_warnoptions,
2125 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002126{
Victor Stinner331a6a52019-05-27 16:39:22 +02002127 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002128 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002129
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002130 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002131 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002132 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002133 * - PyConfig.dev_mode: "default" filter
2134 * - PYTHONWARNINGS environment variable
2135 * - '-W' command line options
2136 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2137 * "default::BytesWarning" or "error::BytesWarning" filter
2138 * - early PySys_AddWarnOption() calls
2139 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002140 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002141 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2142 * module works on the basis of "the most recently added filter will be
2143 * checked first", we add the lowest precedence entries first so that later
2144 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002145 */
2146
Victor Stinner20004952019-03-26 02:31:11 +01002147 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002148 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002149 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002150 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002151 }
2152 }
2153
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002154 status = warnoptions_extend(config, &options, env_warnoptions);
2155 if (_PyStatus_EXCEPTION(status)) {
2156 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002157 }
2158
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002159 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2160 if (_PyStatus_EXCEPTION(status)) {
2161 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002162 }
2163
2164 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2165 * don't even try to emit a warning, so we skip setting the filter in that
2166 * case.
2167 */
2168 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002169 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002170 if (config->bytes_warning> 1) {
2171 filter = L"error::BytesWarning";
2172 }
2173 else {
2174 filter = L"default::BytesWarning";
2175 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002176 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002177 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002178 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002179 }
2180 }
Victor Stinner120b7072019-08-23 18:03:08 +01002181
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002182 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002183 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002184 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002185 }
2186
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002187 /* Always add all PyConfig.warnoptions options */
2188 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2189 if (_PyStatus_EXCEPTION(status)) {
2190 goto error;
2191 }
2192
2193 _PyWideStringList_Clear(&config->warnoptions);
2194 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002195 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002196
2197error:
2198 _PyWideStringList_Clear(&options);
2199 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002200}
2201
2202
Victor Stinner331a6a52019-05-27 16:39:22 +02002203static PyStatus
2204config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002205{
Victor Stinner331a6a52019-05-27 16:39:22 +02002206 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002207 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002208
Victor Stinner74f65682019-03-15 15:08:05 +01002209 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002210 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002211 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002212 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2213 if (_PyStatus_EXCEPTION(status)) {
2214 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002215 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002216 }
2217 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002218 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002219 slice.length = cmdline_argv->length - opt_index;
2220 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002221 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2222 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002223 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002224 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002225 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002226
2227 wchar_t *arg0 = NULL;
2228 if (config->run_command != NULL) {
2229 /* Force sys.argv[0] = '-c' */
2230 arg0 = L"-c";
2231 }
2232 else if (config->run_module != NULL) {
2233 /* Force sys.argv[0] = '-m'*/
2234 arg0 = L"-m";
2235 }
Victor Stinner3939c322019-06-25 15:02:43 +02002236
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002237 if (arg0 != NULL) {
2238 arg0 = _PyMem_RawWcsdup(arg0);
2239 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002240 _PyWideStringList_Clear(&config_argv);
2241 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002242 }
2243
Victor Stinnerfa153762019-03-20 04:25:38 +01002244 PyMem_RawFree(config_argv.items[0]);
2245 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002246 }
2247
Victor Stinner331a6a52019-05-27 16:39:22 +02002248 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002249 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002250 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002251}
2252
2253
Victor Stinner331a6a52019-05-27 16:39:22 +02002254static PyStatus
2255core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002256{
Victor Stinner331a6a52019-05-27 16:39:22 +02002257 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002258
Victor Stinnercab5d072019-05-17 19:01:14 +02002259 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002260 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2261 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002262 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002263 }
2264
Victor Stinner331a6a52019-05-27 16:39:22 +02002265 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002266
2267 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2268 if (_PyStatus_EXCEPTION(status)) {
2269 return status;
2270 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002271
Victor Stinner331a6a52019-05-27 16:39:22 +02002272 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002273
Victor Stinner331a6a52019-05-27 16:39:22 +02002274 status = _PyPreCmdline_Read(precmdline, &preconfig);
2275 if (_PyStatus_EXCEPTION(status)) {
2276 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002277 }
2278
Victor Stinner331a6a52019-05-27 16:39:22 +02002279 status = _PyPreCmdline_SetConfig(precmdline, config);
2280 if (_PyStatus_EXCEPTION(status)) {
2281 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002282 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002283 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002284}
2285
2286
Victor Stinner3939c322019-06-25 15:02:43 +02002287/* Get run_filename absolute path */
2288static PyStatus
2289config_run_filename_abspath(PyConfig *config)
2290{
2291 if (!config->run_filename) {
2292 return _PyStatus_OK();
2293 }
2294
2295#ifndef MS_WINDOWS
2296 if (_Py_isabs(config->run_filename)) {
2297 /* path is already absolute */
2298 return _PyStatus_OK();
2299 }
2300#endif
2301
2302 wchar_t *abs_filename;
2303 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2304 /* failed to get the absolute path of the command line filename:
2305 ignore the error, keep the relative path */
2306 return _PyStatus_OK();
2307 }
2308 if (abs_filename == NULL) {
2309 return _PyStatus_NO_MEMORY();
2310 }
2311
2312 PyMem_RawFree(config->run_filename);
2313 config->run_filename = abs_filename;
2314 return _PyStatus_OK();
2315}
2316
2317
Victor Stinner331a6a52019-05-27 16:39:22 +02002318static PyStatus
2319config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002320{
Victor Stinner331a6a52019-05-27 16:39:22 +02002321 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002322 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2323 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2324 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002325
Victor Stinnerae239f62019-05-16 17:02:56 +02002326 if (config->parse_argv < 0) {
2327 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002328 }
Victor Stinner870b0352019-05-17 03:15:12 +02002329
Victor Stinnerfed02e12019-05-17 11:12:09 +02002330 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002331 status = config_init_program_name(config);
2332 if (_PyStatus_EXCEPTION(status)) {
2333 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002334 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002335 }
Victor Stinner2f549082019-03-29 15:13:46 +01002336
Victor Stinnerae239f62019-05-16 17:02:56 +02002337 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002338 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002339 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2340 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002341 goto done;
2342 }
2343
Victor Stinner3939c322019-06-25 15:02:43 +02002344 status = config_run_filename_abspath(config);
2345 if (_PyStatus_EXCEPTION(status)) {
2346 goto done;
2347 }
2348
Victor Stinner331a6a52019-05-27 16:39:22 +02002349 status = config_update_argv(config, opt_index);
2350 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002351 goto done;
2352 }
Victor Stinner2f549082019-03-29 15:13:46 +01002353 }
Victor Stinner3939c322019-06-25 15:02:43 +02002354 else {
2355 status = config_run_filename_abspath(config);
2356 if (_PyStatus_EXCEPTION(status)) {
2357 goto done;
2358 }
2359 }
Victor Stinner2f549082019-03-29 15:13:46 +01002360
Victor Stinner2f549082019-03-29 15:13:46 +01002361 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002362 status = config_init_env_warnoptions(config, &env_warnoptions);
2363 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002364 goto done;
2365 }
2366 }
2367
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002368 /* Handle early PySys_AddWarnOption() calls */
2369 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2370 if (_PyStatus_EXCEPTION(status)) {
2371 goto done;
2372 }
2373
Victor Stinner331a6a52019-05-27 16:39:22 +02002374 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002375 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002376 &env_warnoptions,
2377 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002378 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002379 goto done;
2380 }
2381
Victor Stinner331a6a52019-05-27 16:39:22 +02002382 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002383
2384done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002385 _PyWideStringList_Clear(&cmdline_warnoptions);
2386 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002387 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002388 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002389}
2390
2391
Victor Stinner331a6a52019-05-27 16:39:22 +02002392PyStatus
2393_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002394{
Victor Stinner331a6a52019-05-27 16:39:22 +02002395 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2396 if (_PyStatus_EXCEPTION(status)) {
2397 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002398 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002399
Victor Stinner5f38b842019-05-01 02:30:12 +02002400 return _PyArgv_AsWstrList(args, &config->argv);
2401}
2402
2403
Victor Stinner70005ac2019-05-02 15:25:34 -04002404/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2405 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002406PyStatus
2407PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002408{
2409 _PyArgv args = {
2410 .argc = argc,
2411 .use_bytes_argv = 1,
2412 .bytes_argv = argv,
2413 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002414 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002415}
2416
2417
Victor Stinner331a6a52019-05-27 16:39:22 +02002418PyStatus
2419PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002420{
2421 _PyArgv args = {
2422 .argc = argc,
2423 .use_bytes_argv = 0,
2424 .bytes_argv = NULL,
2425 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002426 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002427}
2428
2429
Victor Stinner36242fd2019-07-01 19:13:50 +02002430PyStatus
2431PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2432 Py_ssize_t length, wchar_t **items)
2433{
2434 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2435 if (_PyStatus_EXCEPTION(status)) {
2436 return status;
2437 }
2438
2439 PyWideStringList list2 = {.length = length, .items = items};
2440 if (_PyWideStringList_Copy(list, &list2) < 0) {
2441 return _PyStatus_NO_MEMORY();
2442 }
2443 return _PyStatus_OK();
2444}
2445
2446
Victor Stinner331a6a52019-05-27 16:39:22 +02002447/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002448
2449 * Command line arguments
2450 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002451 * Py_xxx global configuration variables
2452
2453 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002454PyStatus
2455PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002456{
Victor Stinner331a6a52019-05-27 16:39:22 +02002457 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002458 PyWideStringList orig_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002459
Victor Stinner331a6a52019-05-27 16:39:22 +02002460 status = _Py_PreInitializeFromConfig(config, NULL);
2461 if (_PyStatus_EXCEPTION(status)) {
2462 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002463 }
2464
Victor Stinner331a6a52019-05-27 16:39:22 +02002465 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002466
Victor Stinner331a6a52019-05-27 16:39:22 +02002467 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2468 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002469 }
2470
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002471 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002472 status = core_read_precmdline(config, &precmdline);
2473 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002474 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002475 }
2476
Victor Stinner870b0352019-05-17 03:15:12 +02002477 assert(config->isolated >= 0);
2478 if (config->isolated) {
2479 config->use_environment = 0;
2480 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002481 }
2482
Victor Stinner331a6a52019-05-27 16:39:22 +02002483 status = config_read_cmdline(config);
2484 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002485 goto done;
2486 }
2487
Victor Stinner120b7072019-08-23 18:03:08 +01002488 /* Handle early PySys_AddXOption() calls */
2489 status = _PySys_ReadPreinitXOptions(config);
2490 if (_PyStatus_EXCEPTION(status)) {
2491 goto done;
2492 }
2493
Victor Stinner331a6a52019-05-27 16:39:22 +02002494 status = config_read(config);
2495 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002496 goto done;
2497 }
2498
Victor Stinnercab5d072019-05-17 19:01:14 +02002499 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002500 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002501 goto done;
2502 }
2503
2504 /* Check config consistency */
2505 assert(config->isolated >= 0);
2506 assert(config->use_environment >= 0);
2507 assert(config->dev_mode >= 0);
2508 assert(config->install_signal_handlers >= 0);
2509 assert(config->use_hash_seed >= 0);
2510 assert(config->faulthandler >= 0);
2511 assert(config->tracemalloc >= 0);
2512 assert(config->site_import >= 0);
2513 assert(config->bytes_warning >= 0);
2514 assert(config->inspect >= 0);
2515 assert(config->interactive >= 0);
2516 assert(config->optimization_level >= 0);
2517 assert(config->parser_debug >= 0);
2518 assert(config->write_bytecode >= 0);
2519 assert(config->verbose >= 0);
2520 assert(config->quiet >= 0);
2521 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002522 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002523 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002524 assert(config->buffered_stdio >= 0);
2525 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002526 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002527 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2528 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002529 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2530 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2531 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002532 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002533 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002534 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002535 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002536 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002537 assert(config->prefix != NULL);
2538 assert(config->base_prefix != NULL);
2539 assert(config->exec_prefix != NULL);
2540 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002541 }
2542 assert(config->filesystem_encoding != NULL);
2543 assert(config->filesystem_errors != NULL);
2544 assert(config->stdio_encoding != NULL);
2545 assert(config->stdio_errors != NULL);
2546#ifdef MS_WINDOWS
2547 assert(config->legacy_windows_stdio >= 0);
2548#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002549 /* -c and -m options are exclusive */
2550 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002551 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002552 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002553 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002554
Victor Stinner331a6a52019-05-27 16:39:22 +02002555 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002556
2557done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002558 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002559 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002560 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002561}
Victor Stinner1075d162019-03-25 23:19:57 +01002562
2563
2564PyObject*
2565_Py_GetConfigsAsDict(void)
2566{
Victor Stinner331a6a52019-05-27 16:39:22 +02002567 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002568 PyObject *dict = NULL;
2569
Victor Stinner331a6a52019-05-27 16:39:22 +02002570 result = PyDict_New();
2571 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002572 goto error;
2573 }
2574
Victor Stinner331a6a52019-05-27 16:39:22 +02002575 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002576 dict = _Py_GetGlobalVariablesAsDict();
2577 if (dict == NULL) {
2578 goto error;
2579 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002580 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002581 goto error;
2582 }
2583 Py_CLEAR(dict);
2584
2585 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002586 PyThreadState *tstate = _PyThreadState_GET();
2587 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002588 dict = _PyPreConfig_AsDict(pre_config);
2589 if (dict == NULL) {
2590 goto error;
2591 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002592 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002593 goto error;
2594 }
2595 Py_CLEAR(dict);
2596
2597 /* core config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002598 const PyConfig *config = &tstate->interp->config;
Victor Stinner331a6a52019-05-27 16:39:22 +02002599 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002600 if (dict == NULL) {
2601 goto error;
2602 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002603 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002604 goto error;
2605 }
2606 Py_CLEAR(dict);
2607
Victor Stinner331a6a52019-05-27 16:39:22 +02002608 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002609
2610error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002611 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002612 Py_XDECREF(dict);
2613 return NULL;
2614}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002615
2616
2617static void
2618init_dump_ascii_wstr(const wchar_t *str)
2619{
2620 if (str == NULL) {
2621 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002622 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002623 }
2624
2625 PySys_WriteStderr("'");
2626 for (; *str != L'\0'; str++) {
2627 wchar_t ch = *str;
2628 if (ch == L'\'') {
2629 PySys_WriteStderr("\\'");
2630 } else if (0x20 <= ch && ch < 0x7f) {
2631 PySys_WriteStderr("%lc", ch);
2632 }
2633 else if (ch <= 0xff) {
2634 PySys_WriteStderr("\\x%02x", ch);
2635 }
2636#if SIZEOF_WCHAR_T > 2
2637 else if (ch > 0xffff) {
2638 PySys_WriteStderr("\\U%08x", ch);
2639 }
2640#endif
2641 else {
2642 PySys_WriteStderr("\\u%04x", ch);
2643 }
2644 }
2645 PySys_WriteStderr("'");
2646}
2647
2648
2649/* Dump the Python path configuration into sys.stderr */
2650void
2651_Py_DumpPathConfig(PyThreadState *tstate)
2652{
2653 PyObject *exc_type, *exc_value, *exc_tb;
2654 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2655
2656 PySys_WriteStderr("Python path configuration:\n");
2657
2658#define DUMP_CONFIG(NAME, FIELD) \
2659 do { \
2660 PySys_WriteStderr(" " NAME " = "); \
2661 init_dump_ascii_wstr(config->FIELD); \
2662 PySys_WriteStderr("\n"); \
2663 } while (0)
2664
2665 PyConfig *config = &tstate->interp->config;
2666 DUMP_CONFIG("PYTHONHOME", home);
2667 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2668 DUMP_CONFIG("program name", program_name);
2669 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2670 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2671 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2672 PySys_WriteStderr(" import site = %i\n", config->site_import);
2673#undef DUMP_CONFIG
2674
2675#define DUMP_SYS(NAME) \
2676 do { \
2677 obj = PySys_GetObject(#NAME); \
2678 PySys_FormatStderr(" sys.%s = ", #NAME); \
2679 if (obj != NULL) { \
2680 PySys_FormatStderr("%A", obj); \
2681 } \
2682 else { \
2683 PySys_WriteStderr("(not set)"); \
2684 } \
2685 PySys_FormatStderr("\n"); \
2686 } while (0)
2687
2688 PyObject *obj;
2689 DUMP_SYS(_base_executable);
2690 DUMP_SYS(base_prefix);
2691 DUMP_SYS(base_exec_prefix);
2692 DUMP_SYS(executable);
2693 DUMP_SYS(prefix);
2694 DUMP_SYS(exec_prefix);
2695#undef DUMP_SYS
2696
2697 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2698 if (sys_path != NULL && PyList_Check(sys_path)) {
2699 PySys_WriteStderr(" sys.path = [\n");
2700 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2701 for (Py_ssize_t i=0; i < len; i++) {
2702 PyObject *path = PyList_GET_ITEM(sys_path, i);
2703 PySys_FormatStderr(" %A,\n", path);
2704 }
2705 PySys_WriteStderr(" ]\n");
2706 }
2707
2708 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2709}