blob: 493b4bb440656b5255a5c2b5acb94a8869a697e2 [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 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001142 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001143 }
1144 }
1145#endif /* WITH_NEXT_FRAMEWORK */
1146#endif /* __APPLE__ */
1147
Victor Stinnerfed02e12019-05-17 11:12:09 +02001148 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001149 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001150 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1151 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1152 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001153 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001154 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001155 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001156 }
1157
Victor Stinnerfed02e12019-05-17 11:12:09 +02001158 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001159#ifdef MS_WINDOWS
1160 const wchar_t *default_program_name = L"python";
1161#else
1162 const wchar_t *default_program_name = L"python3";
1163#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001164 status = PyConfig_SetString(config, &config->program_name,
1165 default_program_name);
1166 if (_PyStatus_EXCEPTION(status)) {
1167 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001168 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001169 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001170}
1171
Victor Stinner331a6a52019-05-27 16:39:22 +02001172static PyStatus
1173config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001174{
1175 assert(config->executable == NULL);
1176
1177 /* If Py_SetProgramFullPath() was called, use its value */
1178 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1179 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001180 PyStatus status = PyConfig_SetString(config,
1181 &config->executable,
1182 program_full_path);
1183 if (_PyStatus_EXCEPTION(status)) {
1184 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001185 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001186 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001187 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001188 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001189}
Victor Stinner6c785c02018-08-01 17:56:14 +02001190
Victor Stinner4fffd382019-03-06 01:44:31 +01001191
Victor Stinner6c785c02018-08-01 17:56:14 +02001192static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001193config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001194{
Victor Stinner74f65682019-03-15 15:08:05 +01001195 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001196}
1197
1198
Victor Stinner331a6a52019-05-27 16:39:22 +02001199static PyStatus
1200config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001201{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001202 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001203
1204 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001205 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001206 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001207 PyStatus status = PyConfig_SetString(config, &config->home, home);
1208 if (_PyStatus_EXCEPTION(status)) {
1209 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001210 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001211 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001212 }
1213
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001214 return CONFIG_GET_ENV_DUP(config, &config->home,
1215 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001216}
1217
1218
Victor Stinner331a6a52019-05-27 16:39:22 +02001219static PyStatus
1220config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001221{
Victor Stinner331a6a52019-05-27 16:39:22 +02001222 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001223
1224 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1225 /* Convert a text seed to a numeric one */
1226 if (seed_text && strcmp(seed_text, "random") != 0) {
1227 const char *endptr = seed_text;
1228 unsigned long seed;
1229 errno = 0;
1230 seed = strtoul(seed_text, (char **)&endptr, 10);
1231 if (*endptr != '\0'
1232 || seed > 4294967295UL
1233 || (errno == ERANGE && seed == ULONG_MAX))
1234 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001235 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001236 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001237 }
1238 /* Use a specific hash */
1239 config->use_hash_seed = 1;
1240 config->hash_seed = seed;
1241 }
1242 else {
1243 /* Use a random hash */
1244 config->use_hash_seed = 0;
1245 config->hash_seed = 0;
1246 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001247 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001248}
1249
1250
Victor Stinner6c785c02018-08-01 17:56:14 +02001251static int
1252config_wstr_to_int(const wchar_t *wstr, int *result)
1253{
1254 const wchar_t *endptr = wstr;
1255 errno = 0;
1256 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1257 if (*endptr != '\0' || errno == ERANGE) {
1258 return -1;
1259 }
1260 if (value < INT_MIN || value > INT_MAX) {
1261 return -1;
1262 }
1263
1264 *result = (int)value;
1265 return 0;
1266}
1267
1268
Victor Stinner331a6a52019-05-27 16:39:22 +02001269static PyStatus
1270config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001271{
Victor Stinner331a6a52019-05-27 16:39:22 +02001272 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001273 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001274
Victor Stinner6c785c02018-08-01 17:56:14 +02001275 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001276 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1277 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1278 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1279 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001280
1281 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001282 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001283 if (dont_write_bytecode) {
1284 config->write_bytecode = 0;
1285 }
1286
1287 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001288 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001289 if (no_user_site_directory) {
1290 config->user_site_directory = 0;
1291 }
1292
1293 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001294 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001295 if (unbuffered_stdio) {
1296 config->buffered_stdio = 0;
1297 }
1298
1299#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001300 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001301 "PYTHONLEGACYWINDOWSSTDIO");
1302#endif
1303
Victor Stinner331a6a52019-05-27 16:39:22 +02001304 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001305 config->dump_refs = 1;
1306 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001307 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001308 config->malloc_stats = 1;
1309 }
1310
Victor Stinner331a6a52019-05-27 16:39:22 +02001311 if (config->pythonpath_env == NULL) {
1312 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1313 L"PYTHONPATH", "PYTHONPATH");
1314 if (_PyStatus_EXCEPTION(status)) {
1315 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001316 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001317 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001318
1319 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001320 status = config_init_hash_seed(config);
1321 if (_PyStatus_EXCEPTION(status)) {
1322 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001323 }
1324 }
1325
Victor Stinner331a6a52019-05-27 16:39:22 +02001326 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001327}
1328
1329
Victor Stinner331a6a52019-05-27 16:39:22 +02001330static PyStatus
1331config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001332{
1333 int nframe;
1334 int valid;
1335
Victor Stinner331a6a52019-05-27 16:39:22 +02001336 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001337 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001338 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001339 valid = (nframe >= 0);
1340 }
1341 else {
1342 valid = 0;
1343 }
1344 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001345 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001346 }
1347 config->tracemalloc = nframe;
1348 }
1349
1350 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1351 if (xoption) {
1352 const wchar_t *sep = wcschr(xoption, L'=');
1353 if (sep) {
1354 if (!config_wstr_to_int(sep + 1, &nframe)) {
1355 valid = (nframe >= 0);
1356 }
1357 else {
1358 valid = 0;
1359 }
1360 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001361 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1362 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001363 }
1364 }
1365 else {
1366 /* -X tracemalloc behaves as -X tracemalloc=1 */
1367 nframe = 1;
1368 }
1369 config->tracemalloc = nframe;
1370 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001371 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001372}
1373
1374
Victor Stinner331a6a52019-05-27 16:39:22 +02001375static PyStatus
1376config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001377{
1378 assert(config->pycache_prefix == NULL);
1379
1380 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1381 if (xoption) {
1382 const wchar_t *sep = wcschr(xoption, L'=');
1383 if (sep && wcslen(sep) > 1) {
1384 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1385 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001386 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001387 }
1388 }
1389 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001390 // PYTHONPYCACHEPREFIX env var ignored
1391 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001392 config->pycache_prefix = NULL;
1393 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001394 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001395 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001396
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001397 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1398 L"PYTHONPYCACHEPREFIX",
1399 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001400}
1401
1402
Victor Stinner331a6a52019-05-27 16:39:22 +02001403static PyStatus
1404config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001405{
1406 /* More complex options configured by env var and -X option */
1407 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001408 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001409 || config_get_xoption(config, L"faulthandler")) {
1410 config->faulthandler = 1;
1411 }
1412 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001413 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001414 || config_get_xoption(config, L"importtime")) {
1415 config->import_time = 1;
1416 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001417
Victor Stinner331a6a52019-05-27 16:39:22 +02001418 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001419 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001420 status = config_init_tracemalloc(config);
1421 if (_PyStatus_EXCEPTION(status)) {
1422 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001423 }
1424 }
1425
1426 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001427 status = config_init_pycache_prefix(config);
1428 if (_PyStatus_EXCEPTION(status)) {
1429 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001430 }
1431 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001432 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001433}
1434
1435
Victor Stinner709d23d2019-05-02 14:56:30 -04001436static const wchar_t *
Victor Stinner331a6a52019-05-27 16:39:22 +02001437config_get_stdio_errors(const PyConfig *config)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001438{
1439#ifndef MS_WINDOWS
1440 const char *loc = setlocale(LC_CTYPE, NULL);
1441 if (loc != NULL) {
1442 /* surrogateescape is the default in the legacy C and POSIX locales */
1443 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001444 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001445 }
1446
1447#ifdef PY_COERCE_C_LOCALE
1448 /* surrogateescape is the default in locale coercion target locales */
1449 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001450 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001451 }
1452#endif
1453 }
1454
Victor Stinner709d23d2019-05-02 14:56:30 -04001455 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001456#else
1457 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001458 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001459#endif
1460}
1461
1462
Victor Stinner331a6a52019-05-27 16:39:22 +02001463static PyStatus
1464config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001465{
1466#ifdef MS_WINDOWS
1467 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001468 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner331a6a52019-05-27 16:39:22 +02001469 return PyConfig_SetBytesString(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001470#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner331a6a52019-05-27 16:39:22 +02001471 return PyConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001472#else
1473 const char *encoding = nl_langinfo(CODESET);
1474 if (!encoding || encoding[0] == '\0') {
Victor Stinner331a6a52019-05-27 16:39:22 +02001475 return _PyStatus_ERR("failed to get the locale encoding: "
1476 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001477 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001478 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner331a6a52019-05-27 16:39:22 +02001479 return CONFIG_SET_BYTES_STR(config,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001480 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001481 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001482#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001483}
1484
1485
Victor Stinner331a6a52019-05-27 16:39:22 +02001486static PyStatus
1487config_init_stdio_encoding(PyConfig *config,
1488 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001489{
Victor Stinner331a6a52019-05-27 16:39:22 +02001490 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001491
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001492 /* If Py_SetStandardStreamEncoding() have been called, use these
1493 parameters. */
1494 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001495 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1496 _Py_StandardStreamEncoding,
1497 "_Py_StandardStreamEncoding");
1498 if (_PyStatus_EXCEPTION(status)) {
1499 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001500 }
1501 }
1502
1503 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001504 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1505 _Py_StandardStreamErrors,
1506 "_Py_StandardStreamErrors");
1507 if (_PyStatus_EXCEPTION(status)) {
1508 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001509 }
1510 }
1511
1512 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001513 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001514 }
1515
1516 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001517 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001518 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001519 char *pythonioencoding = _PyMem_RawStrdup(opt);
1520 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001521 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001522 }
1523
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001524 char *errors = strchr(pythonioencoding, ':');
1525 if (errors) {
1526 *errors = '\0';
1527 errors++;
1528 if (!errors[0]) {
1529 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001530 }
1531 }
1532
1533 /* Does PYTHONIOENCODING contain an encoding? */
1534 if (pythonioencoding[0]) {
1535 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001536 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1537 pythonioencoding,
1538 "PYTHONIOENCODING environment variable");
1539 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001540 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001541 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001542 }
1543 }
1544
1545 /* If the encoding is set but not the error handler,
1546 use "strict" error handler by default.
1547 PYTHONIOENCODING=latin1 behaves as
1548 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001549 if (!errors) {
1550 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001551 }
1552 }
1553
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001554 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001555 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1556 errors,
1557 "PYTHONIOENCODING environment variable");
1558 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001559 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001560 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001561 }
1562 }
1563
1564 PyMem_RawFree(pythonioencoding);
1565 }
1566
1567 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001568 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001569 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001570 status = PyConfig_SetString(config, &config->stdio_encoding,
1571 L"utf-8");
1572 if (_PyStatus_EXCEPTION(status)) {
1573 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001574 }
1575 }
1576 if (config->stdio_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001577 status = PyConfig_SetString(config, &config->stdio_errors,
1578 L"surrogateescape");
1579 if (_PyStatus_EXCEPTION(status)) {
1580 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001581 }
1582 }
1583 }
1584
1585 /* Choose the default error handler based on the current locale. */
1586 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001587 status = config_get_locale_encoding(config, &config->stdio_encoding);
1588 if (_PyStatus_EXCEPTION(status)) {
1589 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001590 }
1591 }
1592 if (config->stdio_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001593 const wchar_t *errors = config_get_stdio_errors(config);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001594 assert(errors != NULL);
1595
Victor Stinner331a6a52019-05-27 16:39:22 +02001596 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1597 if (_PyStatus_EXCEPTION(status)) {
1598 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001599 }
1600 }
1601
Victor Stinner331a6a52019-05-27 16:39:22 +02001602 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001603}
1604
1605
Victor Stinner331a6a52019-05-27 16:39:22 +02001606static PyStatus
1607config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001608{
Victor Stinner331a6a52019-05-27 16:39:22 +02001609 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001610
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001611 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001612#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner331a6a52019-05-27 16:39:22 +02001613 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001614#else
Victor Stinnere2510952019-05-02 11:28:57 -04001615
1616#ifdef MS_WINDOWS
1617 if (preconfig->legacy_windows_fs_encoding) {
1618 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner331a6a52019-05-27 16:39:22 +02001619 status = PyConfig_SetString(config, &config->filesystem_encoding,
1620 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001621 }
1622 else
1623#endif
Victor Stinner20004952019-03-26 02:31:11 +01001624 if (preconfig->utf8_mode) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001625 status = PyConfig_SetString(config, &config->filesystem_encoding,
1626 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001627 }
Victor Stinnere2510952019-05-02 11:28:57 -04001628#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001629 else if (_Py_GetForceASCII()) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001630 status = PyConfig_SetString(config, &config->filesystem_encoding,
1631 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001632 }
Victor Stinnere2510952019-05-02 11:28:57 -04001633#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001634 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001635#ifdef MS_WINDOWS
1636 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner331a6a52019-05-27 16:39:22 +02001637 status = PyConfig_SetString(config, &config->filesystem_encoding,
1638 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001639#else
Victor Stinner331a6a52019-05-27 16:39:22 +02001640 status = config_get_locale_encoding(config,
1641 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001642#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001643 }
Victor Stinnere2510952019-05-02 11:28:57 -04001644#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001645
Victor Stinner331a6a52019-05-27 16:39:22 +02001646 if (_PyStatus_EXCEPTION(status)) {
1647 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001648 }
1649 }
1650
1651 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001652 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001653#ifdef MS_WINDOWS
1654 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001655 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001656 }
1657 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001658 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001659 }
1660#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001661 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001662#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001663 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1664 if (_PyStatus_EXCEPTION(status)) {
1665 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001666 }
1667 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001668 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001669}
1670
1671
Victor Stinner331a6a52019-05-27 16:39:22 +02001672static PyStatus
1673config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001674{
Victor Stinner331a6a52019-05-27 16:39:22 +02001675 PyStatus status;
1676 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001677
Victor Stinner20004952019-03-26 02:31:11 +01001678 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001679 status = config_read_env_vars(config);
1680 if (_PyStatus_EXCEPTION(status)) {
1681 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001682 }
1683 }
1684
1685 /* -X options */
1686 if (config_get_xoption(config, L"showrefcount")) {
1687 config->show_ref_count = 1;
1688 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001689
Victor Stinner331a6a52019-05-27 16:39:22 +02001690 status = config_read_complex_options(config);
1691 if (_PyStatus_EXCEPTION(status)) {
1692 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001693 }
1694
Victor Stinner6c785c02018-08-01 17:56:14 +02001695 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001696 status = config_init_home(config);
1697 if (_PyStatus_EXCEPTION(status)) {
1698 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001699 }
1700 }
1701
Steve Dower177a41a2018-11-17 20:41:48 -08001702 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001703 status = config_init_executable(config);
1704 if (_PyStatus_EXCEPTION(status)) {
1705 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001706 }
1707 }
1708
Victor Stinner6c785c02018-08-01 17:56:14 +02001709 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001710 status = _PyConfig_InitPathConfig(config);
1711 if (_PyStatus_EXCEPTION(status)) {
1712 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001713 }
1714 }
1715
1716 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001717 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001718 if (config->faulthandler < 0) {
1719 config->faulthandler = 1;
1720 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001721 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001722 if (config->faulthandler < 0) {
1723 config->faulthandler = 0;
1724 }
1725 if (config->tracemalloc < 0) {
1726 config->tracemalloc = 0;
1727 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001728 if (config->use_hash_seed < 0) {
1729 config->use_hash_seed = 0;
1730 config->hash_seed = 0;
1731 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001732
Victor Stinner70fead22018-08-29 13:45:34 +02001733 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001734 status = config_init_fs_encoding(config, preconfig);
1735 if (_PyStatus_EXCEPTION(status)) {
1736 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001737 }
1738 }
1739
Victor Stinner331a6a52019-05-27 16:39:22 +02001740 status = config_init_stdio_encoding(config, preconfig);
1741 if (_PyStatus_EXCEPTION(status)) {
1742 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001743 }
1744
Victor Stinner62599762019-03-15 16:03:23 +01001745 if (config->argv.length < 1) {
1746 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02001747 status = PyWideStringList_Append(&config->argv, L"");
1748 if (_PyStatus_EXCEPTION(status)) {
1749 return status;
Victor Stinner62599762019-03-15 16:03:23 +01001750 }
1751 }
Victor Stinner870b0352019-05-17 03:15:12 +02001752
1753 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001754 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1755 L"default");
1756 if (_PyStatus_EXCEPTION(status)) {
1757 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02001758 }
1759 }
1760
1761 if (config->configure_c_stdio < 0) {
1762 config->configure_c_stdio = 1;
1763 }
1764
Victor Stinner331a6a52019-05-27 16:39:22 +02001765 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001766}
Victor Stinner5ed69952018-11-06 15:59:52 +01001767
1768
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001769static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001770config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001771{
1772#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1773 /* don't translate newlines (\r\n <=> \n) */
1774 _setmode(fileno(stdin), O_BINARY);
1775 _setmode(fileno(stdout), O_BINARY);
1776 _setmode(fileno(stderr), O_BINARY);
1777#endif
1778
1779 if (!config->buffered_stdio) {
1780#ifdef HAVE_SETVBUF
1781 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1782 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1783 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1784#else /* !HAVE_SETVBUF */
1785 setbuf(stdin, (char *)NULL);
1786 setbuf(stdout, (char *)NULL);
1787 setbuf(stderr, (char *)NULL);
1788#endif /* !HAVE_SETVBUF */
1789 }
1790 else if (config->interactive) {
1791#ifdef MS_WINDOWS
1792 /* Doesn't have to have line-buffered -- use unbuffered */
1793 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1794 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1795#else /* !MS_WINDOWS */
1796#ifdef HAVE_SETVBUF
1797 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1798 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1799#endif /* HAVE_SETVBUF */
1800#endif /* !MS_WINDOWS */
1801 /* Leave stderr alone - it should be unbuffered anyway. */
1802 }
1803}
1804
1805
1806/* Write the configuration:
1807
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001808 - set Py_xxx global configuration variables
1809 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001810void
Victor Stinner331a6a52019-05-27 16:39:22 +02001811_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001812{
Victor Stinner331a6a52019-05-27 16:39:22 +02001813 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001814
1815 if (config->configure_c_stdio) {
1816 config_init_stdio(config);
1817 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001818
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001819 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02001820 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001821 preconfig->isolated = config->isolated;
1822 preconfig->use_environment = config->use_environment;
1823 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001824}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001825
1826
Victor Stinner331a6a52019-05-27 16:39:22 +02001827/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001828
1829static void
Victor Stinner2f549082019-03-29 15:13:46 +01001830config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001831{
Victor Stinner2f549082019-03-29 15:13:46 +01001832 FILE *f = error ? stderr : stdout;
1833
1834 fprintf(f, usage_line, program);
1835 if (error)
1836 fprintf(f, "Try `python -h' for more information.\n");
1837 else {
1838 fputs(usage_1, f);
1839 fputs(usage_2, f);
1840 fputs(usage_3, f);
1841 fprintf(f, usage_4, (wint_t)DELIM);
1842 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1843 fputs(usage_6, f);
1844 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001845}
1846
1847
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001848/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02001849static PyStatus
1850config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001851 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001852{
Victor Stinner331a6a52019-05-27 16:39:22 +02001853 PyStatus status;
1854 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001855 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001856 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001857
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001858 _PyOS_ResetGetOpt();
1859 do {
1860 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001861 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001862 if (c == EOF) {
1863 break;
1864 }
1865
1866 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001867 if (config->run_command == NULL) {
1868 /* -c is the last option; following arguments
1869 that look like options are left for the
1870 command to interpret. */
1871 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1872 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1873 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001874 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001875 }
1876 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1877 command[len - 2] = '\n';
1878 command[len - 1] = 0;
1879 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001880 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001881 break;
1882 }
1883
1884 if (c == 'm') {
1885 /* -m is the last option; following arguments
1886 that look like options are left for the
1887 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001888 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001889 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1890 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001891 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01001892 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001893 }
1894 break;
1895 }
1896
1897 switch (c) {
1898 case 0:
1899 // Handle long option.
1900 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001901 if (wcscmp(_PyOS_optarg, L"always") == 0
1902 || wcscmp(_PyOS_optarg, L"never") == 0
1903 || wcscmp(_PyOS_optarg, L"default") == 0)
1904 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001905 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1906 _PyOS_optarg);
1907 if (_PyStatus_EXCEPTION(status)) {
1908 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001909 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001910 } else {
1911 fprintf(stderr, "--check-hash-based-pycs must be one of "
1912 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001913 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001914 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001915 }
1916 break;
1917
1918 case 'b':
1919 config->bytes_warning++;
1920 break;
1921
1922 case 'd':
1923 config->parser_debug++;
1924 break;
1925
1926 case 'i':
1927 config->inspect++;
1928 config->interactive++;
1929 break;
1930
Victor Stinner6dcb5422019-03-05 02:44:12 +01001931 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001932 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001933 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001934 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001935 break;
1936
1937 /* case 'J': reserved for Jython */
1938
1939 case 'O':
1940 config->optimization_level++;
1941 break;
1942
1943 case 'B':
1944 config->write_bytecode = 0;
1945 break;
1946
1947 case 's':
1948 config->user_site_directory = 0;
1949 break;
1950
1951 case 'S':
1952 config->site_import = 0;
1953 break;
1954
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001955 case 't':
1956 /* ignored for backwards compatibility */
1957 break;
1958
1959 case 'u':
1960 config->buffered_stdio = 0;
1961 break;
1962
1963 case 'v':
1964 config->verbose++;
1965 break;
1966
1967 case 'x':
1968 config->skip_source_first_line = 1;
1969 break;
1970
1971 case 'h':
1972 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001973 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02001974 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001975
1976 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01001977 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001978 break;
1979
1980 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02001981 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
1982 if (_PyStatus_EXCEPTION(status)) {
1983 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001984 }
1985 break;
1986
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001987 case 'q':
1988 config->quiet++;
1989 break;
1990
1991 case 'R':
1992 config->use_hash_seed = 0;
1993 break;
1994
1995 /* This space reserved for other options */
1996
1997 default:
1998 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02001999 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002000 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002001 }
2002 } while (1);
2003
Victor Stinner2f549082019-03-29 15:13:46 +01002004 if (print_version) {
2005 printf("Python %s\n",
2006 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002007 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002008 }
2009
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002010 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002011 && _PyOS_optind < argv->length
2012 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002013 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002014 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002015 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002016 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002017 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002018 }
2019 }
2020
2021 if (config->run_command != NULL || config->run_module != NULL) {
2022 /* Backup _PyOS_optind */
2023 _PyOS_optind--;
2024 }
2025
Victor Stinnerae239f62019-05-16 17:02:56 +02002026 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002027
Victor Stinner331a6a52019-05-27 16:39:22 +02002028 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002029}
2030
2031
2032#ifdef MS_WINDOWS
2033# define WCSTOK wcstok_s
2034#else
2035# define WCSTOK wcstok
2036#endif
2037
2038/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002039static PyStatus
2040config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002041{
Victor Stinner331a6a52019-05-27 16:39:22 +02002042 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002043 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2044 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002045 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002046 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002047 if (_PyStatus_EXCEPTION(status)) {
2048 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002049 }
2050
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002051 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002052 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002053 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002054 }
2055
2056
2057 wchar_t *warning, *context = NULL;
2058 for (warning = WCSTOK(env, L",", &context);
2059 warning != NULL;
2060 warning = WCSTOK(NULL, L",", &context))
2061 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002062 status = PyWideStringList_Append(warnoptions, warning);
2063 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002064 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002065 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002066 }
2067 }
2068 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002069 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002070}
2071
2072
Victor Stinner331a6a52019-05-27 16:39:22 +02002073static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002074warnoptions_append(PyConfig *config, PyWideStringList *options,
2075 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002076{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002077 /* config_init_warnoptions() add existing config warnoptions at the end:
2078 ensure that the new option is not already present in this list to
2079 prevent change the options order whne config_init_warnoptions() is
2080 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002081 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002082 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002083 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002084 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002085 if (_PyWideStringList_Find(options, option)) {
2086 /* Already present: do nothing */
2087 return _PyStatus_OK();
2088 }
2089 return PyWideStringList_Append(options, option);
2090}
2091
2092
2093static PyStatus
2094warnoptions_extend(PyConfig *config, PyWideStringList *options,
2095 const PyWideStringList *options2)
2096{
2097 const Py_ssize_t len = options2->length;
2098 wchar_t *const *items = options2->items;
2099
2100 for (Py_ssize_t i = 0; i < len; i++) {
2101 PyStatus status = warnoptions_append(config, options, items[i]);
2102 if (_PyStatus_EXCEPTION(status)) {
2103 return status;
2104 }
2105 }
2106 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002107}
2108
2109
Victor Stinner331a6a52019-05-27 16:39:22 +02002110static PyStatus
2111config_init_warnoptions(PyConfig *config,
2112 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002113 const PyWideStringList *env_warnoptions,
2114 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002115{
Victor Stinner331a6a52019-05-27 16:39:22 +02002116 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002117 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002118
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002119 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002120 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002121 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002122 * - PyConfig.dev_mode: "default" filter
2123 * - PYTHONWARNINGS environment variable
2124 * - '-W' command line options
2125 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2126 * "default::BytesWarning" or "error::BytesWarning" filter
2127 * - early PySys_AddWarnOption() calls
2128 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002129 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002130 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2131 * module works on the basis of "the most recently added filter will be
2132 * checked first", we add the lowest precedence entries first so that later
2133 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002134 */
2135
Victor Stinner20004952019-03-26 02:31:11 +01002136 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002137 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002138 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002139 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002140 }
2141 }
2142
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002143 status = warnoptions_extend(config, &options, env_warnoptions);
2144 if (_PyStatus_EXCEPTION(status)) {
2145 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002146 }
2147
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002148 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2149 if (_PyStatus_EXCEPTION(status)) {
2150 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002151 }
2152
2153 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2154 * don't even try to emit a warning, so we skip setting the filter in that
2155 * case.
2156 */
2157 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002158 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002159 if (config->bytes_warning> 1) {
2160 filter = L"error::BytesWarning";
2161 }
2162 else {
2163 filter = L"default::BytesWarning";
2164 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002165 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002166 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002167 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002168 }
2169 }
Victor Stinner120b7072019-08-23 18:03:08 +01002170
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002171 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002172 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002173 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002174 }
2175
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002176 /* Always add all PyConfig.warnoptions options */
2177 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2178 if (_PyStatus_EXCEPTION(status)) {
2179 goto error;
2180 }
2181
2182 _PyWideStringList_Clear(&config->warnoptions);
2183 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002184 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002185
2186error:
2187 _PyWideStringList_Clear(&options);
2188 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002189}
2190
2191
Victor Stinner331a6a52019-05-27 16:39:22 +02002192static PyStatus
2193config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002194{
Victor Stinner331a6a52019-05-27 16:39:22 +02002195 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002196 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002197
Victor Stinner74f65682019-03-15 15:08:05 +01002198 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002199 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002200 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002201 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2202 if (_PyStatus_EXCEPTION(status)) {
2203 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002204 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002205 }
2206 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002207 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002208 slice.length = cmdline_argv->length - opt_index;
2209 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002210 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2211 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002212 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002213 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002214 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002215
2216 wchar_t *arg0 = NULL;
2217 if (config->run_command != NULL) {
2218 /* Force sys.argv[0] = '-c' */
2219 arg0 = L"-c";
2220 }
2221 else if (config->run_module != NULL) {
2222 /* Force sys.argv[0] = '-m'*/
2223 arg0 = L"-m";
2224 }
Victor Stinner3939c322019-06-25 15:02:43 +02002225
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002226 if (arg0 != NULL) {
2227 arg0 = _PyMem_RawWcsdup(arg0);
2228 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002229 _PyWideStringList_Clear(&config_argv);
2230 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002231 }
2232
Victor Stinnerfa153762019-03-20 04:25:38 +01002233 PyMem_RawFree(config_argv.items[0]);
2234 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002235 }
2236
Victor Stinner331a6a52019-05-27 16:39:22 +02002237 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002238 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002239 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002240}
2241
2242
Victor Stinner331a6a52019-05-27 16:39:22 +02002243static PyStatus
2244core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002245{
Victor Stinner331a6a52019-05-27 16:39:22 +02002246 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002247
Victor Stinnercab5d072019-05-17 19:01:14 +02002248 if (config->parse_argv) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002249 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2250 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002251 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002252 }
2253
Victor Stinner331a6a52019-05-27 16:39:22 +02002254 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002255
2256 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2257 if (_PyStatus_EXCEPTION(status)) {
2258 return status;
2259 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002260
Victor Stinner331a6a52019-05-27 16:39:22 +02002261 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002262
Victor Stinner331a6a52019-05-27 16:39:22 +02002263 status = _PyPreCmdline_Read(precmdline, &preconfig);
2264 if (_PyStatus_EXCEPTION(status)) {
2265 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002266 }
2267
Victor Stinner331a6a52019-05-27 16:39:22 +02002268 status = _PyPreCmdline_SetConfig(precmdline, config);
2269 if (_PyStatus_EXCEPTION(status)) {
2270 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002271 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002272 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002273}
2274
2275
Victor Stinner3939c322019-06-25 15:02:43 +02002276/* Get run_filename absolute path */
2277static PyStatus
2278config_run_filename_abspath(PyConfig *config)
2279{
2280 if (!config->run_filename) {
2281 return _PyStatus_OK();
2282 }
2283
2284#ifndef MS_WINDOWS
2285 if (_Py_isabs(config->run_filename)) {
2286 /* path is already absolute */
2287 return _PyStatus_OK();
2288 }
2289#endif
2290
2291 wchar_t *abs_filename;
2292 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2293 /* failed to get the absolute path of the command line filename:
2294 ignore the error, keep the relative path */
2295 return _PyStatus_OK();
2296 }
2297 if (abs_filename == NULL) {
2298 return _PyStatus_NO_MEMORY();
2299 }
2300
2301 PyMem_RawFree(config->run_filename);
2302 config->run_filename = abs_filename;
2303 return _PyStatus_OK();
2304}
2305
2306
Victor Stinner331a6a52019-05-27 16:39:22 +02002307static PyStatus
2308config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002309{
Victor Stinner331a6a52019-05-27 16:39:22 +02002310 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002311 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2312 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2313 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002314
Victor Stinnerae239f62019-05-16 17:02:56 +02002315 if (config->parse_argv < 0) {
2316 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002317 }
Victor Stinner870b0352019-05-17 03:15:12 +02002318
Victor Stinnerfed02e12019-05-17 11:12:09 +02002319 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002320 status = config_init_program_name(config);
2321 if (_PyStatus_EXCEPTION(status)) {
2322 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002323 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002324 }
Victor Stinner2f549082019-03-29 15:13:46 +01002325
Victor Stinnerae239f62019-05-16 17:02:56 +02002326 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002327 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002328 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2329 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002330 goto done;
2331 }
2332
Victor Stinner3939c322019-06-25 15:02:43 +02002333 status = config_run_filename_abspath(config);
2334 if (_PyStatus_EXCEPTION(status)) {
2335 goto done;
2336 }
2337
Victor Stinner331a6a52019-05-27 16:39:22 +02002338 status = config_update_argv(config, opt_index);
2339 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002340 goto done;
2341 }
Victor Stinner2f549082019-03-29 15:13:46 +01002342 }
Victor Stinner3939c322019-06-25 15:02:43 +02002343 else {
2344 status = config_run_filename_abspath(config);
2345 if (_PyStatus_EXCEPTION(status)) {
2346 goto done;
2347 }
2348 }
Victor Stinner2f549082019-03-29 15:13:46 +01002349
Victor Stinner2f549082019-03-29 15:13:46 +01002350 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002351 status = config_init_env_warnoptions(config, &env_warnoptions);
2352 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002353 goto done;
2354 }
2355 }
2356
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002357 /* Handle early PySys_AddWarnOption() calls */
2358 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2359 if (_PyStatus_EXCEPTION(status)) {
2360 goto done;
2361 }
2362
Victor Stinner331a6a52019-05-27 16:39:22 +02002363 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002364 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002365 &env_warnoptions,
2366 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002367 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002368 goto done;
2369 }
2370
Victor Stinner331a6a52019-05-27 16:39:22 +02002371 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002372
2373done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002374 _PyWideStringList_Clear(&cmdline_warnoptions);
2375 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002376 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002377 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002378}
2379
2380
Victor Stinner331a6a52019-05-27 16:39:22 +02002381PyStatus
2382_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002383{
Victor Stinner331a6a52019-05-27 16:39:22 +02002384 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2385 if (_PyStatus_EXCEPTION(status)) {
2386 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002387 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002388
Victor Stinner5f38b842019-05-01 02:30:12 +02002389 return _PyArgv_AsWstrList(args, &config->argv);
2390}
2391
2392
Victor Stinner70005ac2019-05-02 15:25:34 -04002393/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2394 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002395PyStatus
2396PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002397{
2398 _PyArgv args = {
2399 .argc = argc,
2400 .use_bytes_argv = 1,
2401 .bytes_argv = argv,
2402 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002403 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002404}
2405
2406
Victor Stinner331a6a52019-05-27 16:39:22 +02002407PyStatus
2408PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002409{
2410 _PyArgv args = {
2411 .argc = argc,
2412 .use_bytes_argv = 0,
2413 .bytes_argv = NULL,
2414 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002415 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002416}
2417
2418
Victor Stinner36242fd2019-07-01 19:13:50 +02002419PyStatus
2420PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2421 Py_ssize_t length, wchar_t **items)
2422{
2423 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2424 if (_PyStatus_EXCEPTION(status)) {
2425 return status;
2426 }
2427
2428 PyWideStringList list2 = {.length = length, .items = items};
2429 if (_PyWideStringList_Copy(list, &list2) < 0) {
2430 return _PyStatus_NO_MEMORY();
2431 }
2432 return _PyStatus_OK();
2433}
2434
2435
Victor Stinner331a6a52019-05-27 16:39:22 +02002436/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002437
2438 * Command line arguments
2439 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002440 * Py_xxx global configuration variables
2441
2442 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002443PyStatus
2444PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002445{
Victor Stinner331a6a52019-05-27 16:39:22 +02002446 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002447 PyWideStringList orig_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002448
Victor Stinner331a6a52019-05-27 16:39:22 +02002449 status = _Py_PreInitializeFromConfig(config, NULL);
2450 if (_PyStatus_EXCEPTION(status)) {
2451 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002452 }
2453
Victor Stinner331a6a52019-05-27 16:39:22 +02002454 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002455
Victor Stinner331a6a52019-05-27 16:39:22 +02002456 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2457 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002458 }
2459
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002460 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002461 status = core_read_precmdline(config, &precmdline);
2462 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002463 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002464 }
2465
Victor Stinner870b0352019-05-17 03:15:12 +02002466 assert(config->isolated >= 0);
2467 if (config->isolated) {
2468 config->use_environment = 0;
2469 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002470 }
2471
Victor Stinner331a6a52019-05-27 16:39:22 +02002472 status = config_read_cmdline(config);
2473 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002474 goto done;
2475 }
2476
Victor Stinner120b7072019-08-23 18:03:08 +01002477 /* Handle early PySys_AddXOption() calls */
2478 status = _PySys_ReadPreinitXOptions(config);
2479 if (_PyStatus_EXCEPTION(status)) {
2480 goto done;
2481 }
2482
Victor Stinner331a6a52019-05-27 16:39:22 +02002483 status = config_read(config);
2484 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002485 goto done;
2486 }
2487
Victor Stinnercab5d072019-05-17 19:01:14 +02002488 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002489 status = _PyStatus_NO_MEMORY();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002490 goto done;
2491 }
2492
2493 /* Check config consistency */
2494 assert(config->isolated >= 0);
2495 assert(config->use_environment >= 0);
2496 assert(config->dev_mode >= 0);
2497 assert(config->install_signal_handlers >= 0);
2498 assert(config->use_hash_seed >= 0);
2499 assert(config->faulthandler >= 0);
2500 assert(config->tracemalloc >= 0);
2501 assert(config->site_import >= 0);
2502 assert(config->bytes_warning >= 0);
2503 assert(config->inspect >= 0);
2504 assert(config->interactive >= 0);
2505 assert(config->optimization_level >= 0);
2506 assert(config->parser_debug >= 0);
2507 assert(config->write_bytecode >= 0);
2508 assert(config->verbose >= 0);
2509 assert(config->quiet >= 0);
2510 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002511 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002512 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002513 assert(config->buffered_stdio >= 0);
2514 assert(config->program_name != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +02002515 assert(_PyWideStringList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002516 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2517 assert(config->argv.length >= 1);
Victor Stinner331a6a52019-05-27 16:39:22 +02002518 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2519 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2520 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002521 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002522 assert(config->module_search_paths_set != 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002523 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002524 assert(config->executable != NULL);
Steve Dower9048c492019-06-29 10:34:11 -07002525 assert(config->base_executable != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002526 assert(config->prefix != NULL);
2527 assert(config->base_prefix != NULL);
2528 assert(config->exec_prefix != NULL);
2529 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002530 }
2531 assert(config->filesystem_encoding != NULL);
2532 assert(config->filesystem_errors != NULL);
2533 assert(config->stdio_encoding != NULL);
2534 assert(config->stdio_errors != NULL);
2535#ifdef MS_WINDOWS
2536 assert(config->legacy_windows_stdio >= 0);
2537#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002538 /* -c and -m options are exclusive */
2539 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002540 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002541 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002542 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002543
Victor Stinner331a6a52019-05-27 16:39:22 +02002544 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002545
2546done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002547 _PyWideStringList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002548 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002549 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002550}
Victor Stinner1075d162019-03-25 23:19:57 +01002551
2552
2553PyObject*
2554_Py_GetConfigsAsDict(void)
2555{
Victor Stinner331a6a52019-05-27 16:39:22 +02002556 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002557 PyObject *dict = NULL;
2558
Victor Stinner331a6a52019-05-27 16:39:22 +02002559 result = PyDict_New();
2560 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002561 goto error;
2562 }
2563
Victor Stinner331a6a52019-05-27 16:39:22 +02002564 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002565 dict = _Py_GetGlobalVariablesAsDict();
2566 if (dict == NULL) {
2567 goto error;
2568 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002569 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002570 goto error;
2571 }
2572 Py_CLEAR(dict);
2573
2574 /* pre config */
2575 PyInterpreterState *interp = _PyInterpreterState_Get();
Victor Stinner331a6a52019-05-27 16:39:22 +02002576 const PyPreConfig *pre_config = &_PyRuntime.preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002577 dict = _PyPreConfig_AsDict(pre_config);
2578 if (dict == NULL) {
2579 goto error;
2580 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002581 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002582 goto error;
2583 }
2584 Py_CLEAR(dict);
2585
2586 /* core config */
Victor Stinner331a6a52019-05-27 16:39:22 +02002587 const PyConfig *config = &interp->config;
2588 dict = config_as_dict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002589 if (dict == NULL) {
2590 goto error;
2591 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002592 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002593 goto error;
2594 }
2595 Py_CLEAR(dict);
2596
Victor Stinner331a6a52019-05-27 16:39:22 +02002597 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002598
2599error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002600 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002601 Py_XDECREF(dict);
2602 return NULL;
2603}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002604
2605
2606static void
2607init_dump_ascii_wstr(const wchar_t *str)
2608{
2609 if (str == NULL) {
2610 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002611 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002612 }
2613
2614 PySys_WriteStderr("'");
2615 for (; *str != L'\0'; str++) {
2616 wchar_t ch = *str;
2617 if (ch == L'\'') {
2618 PySys_WriteStderr("\\'");
2619 } else if (0x20 <= ch && ch < 0x7f) {
2620 PySys_WriteStderr("%lc", ch);
2621 }
2622 else if (ch <= 0xff) {
2623 PySys_WriteStderr("\\x%02x", ch);
2624 }
2625#if SIZEOF_WCHAR_T > 2
2626 else if (ch > 0xffff) {
2627 PySys_WriteStderr("\\U%08x", ch);
2628 }
2629#endif
2630 else {
2631 PySys_WriteStderr("\\u%04x", ch);
2632 }
2633 }
2634 PySys_WriteStderr("'");
2635}
2636
2637
2638/* Dump the Python path configuration into sys.stderr */
2639void
2640_Py_DumpPathConfig(PyThreadState *tstate)
2641{
2642 PyObject *exc_type, *exc_value, *exc_tb;
2643 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2644
2645 PySys_WriteStderr("Python path configuration:\n");
2646
2647#define DUMP_CONFIG(NAME, FIELD) \
2648 do { \
2649 PySys_WriteStderr(" " NAME " = "); \
2650 init_dump_ascii_wstr(config->FIELD); \
2651 PySys_WriteStderr("\n"); \
2652 } while (0)
2653
2654 PyConfig *config = &tstate->interp->config;
2655 DUMP_CONFIG("PYTHONHOME", home);
2656 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2657 DUMP_CONFIG("program name", program_name);
2658 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2659 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2660 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2661 PySys_WriteStderr(" import site = %i\n", config->site_import);
2662#undef DUMP_CONFIG
2663
2664#define DUMP_SYS(NAME) \
2665 do { \
2666 obj = PySys_GetObject(#NAME); \
2667 PySys_FormatStderr(" sys.%s = ", #NAME); \
2668 if (obj != NULL) { \
2669 PySys_FormatStderr("%A", obj); \
2670 } \
2671 else { \
2672 PySys_WriteStderr("(not set)"); \
2673 } \
2674 PySys_FormatStderr("\n"); \
2675 } while (0)
2676
2677 PyObject *obj;
2678 DUMP_SYS(_base_executable);
2679 DUMP_SYS(base_prefix);
2680 DUMP_SYS(base_exec_prefix);
2681 DUMP_SYS(executable);
2682 DUMP_SYS(prefix);
2683 DUMP_SYS(exec_prefix);
2684#undef DUMP_SYS
2685
2686 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2687 if (sys_path != NULL && PyList_Check(sys_path)) {
2688 PySys_WriteStderr(" sys.path = [\n");
2689 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2690 for (Py_ssize_t i=0; i < len; i++) {
2691 PyObject *path = PyList_GET_ITEM(sys_path, i);
2692 PySys_FormatStderr(" %A,\n", path);
2693 }
2694 PySys_WriteStderr(" ]\n");
2695 }
2696
2697 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2698}