blob: 470bda870288b56f4325287c62eedcbc27fd356d [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 Stinnerf684d832019-03-01 03:44:13 +01003#include "pycore_coreconfig.h"
Victor Stinner9fc57a32018-11-07 00:44:03 +01004#include "pycore_fileutils.h"
Victor Stinner95e2cbf2019-03-01 16:25:19 +01005#include "pycore_getopt.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01006#include "pycore_pylifecycle.h"
7#include "pycore_pymem.h"
Victor Stinner6d5ee972019-03-23 12:05:43 +01008#include "pycore_pystate.h" /* _PyRuntime */
Victor Stinnera1c249c2018-11-01 03:15:58 +01009#include "pycore_pathconfig.h"
Victor Stinner95e2cbf2019-03-01 16:25:19 +010010#include <locale.h> /* setlocale() */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020011#ifdef HAVE_LANGINFO_H
Victor Stinner95e2cbf2019-03-01 16:25:19 +010012# include <langinfo.h> /* nl_langinfo(CODESET) */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020013#endif
Victor Stinner95e2cbf2019-03-01 16:25:19 +010014#if defined(MS_WINDOWS) || defined(__CYGWIN__)
15# include <windows.h> /* GetACP() */
16# ifdef HAVE_IO_H
17# include <io.h>
18# endif
19# ifdef HAVE_FCNTL_H
20# include <fcntl.h> /* O_BINARY */
21# endif
Victor Stinnerb2457ef2018-08-29 13:25:36 +020022#endif
23
Victor Stinner6c785c02018-08-01 17:56:14 +020024
Victor Stinner95e2cbf2019-03-01 16:25:19 +010025/* --- Command line options --------------------------------------- */
26
Victor Stinner95e2cbf2019-03-01 16:25:19 +010027/* Short usage message (with %s for argv0) */
28static const char usage_line[] =
29"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
30
31/* Long usage message, split into parts < 512 bytes */
32static const char usage_1[] = "\
33Options and arguments (and corresponding environment variables):\n\
34-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
35 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
36-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
37-c cmd : program passed in as string (terminates option list)\n\
38-d : debug output from parser; also PYTHONDEBUG=x\n\
39-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
40-h : print this help message and exit (also --help)\n\
41";
42static const char usage_2[] = "\
43-i : inspect interactively after running script; forces a prompt even\n\
44 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
45-I : isolate Python from the user's environment (implies -E and -s)\n\
46-m mod : run library module as a script (terminates option list)\n\
47-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
48 .pyc extension; also PYTHONOPTIMIZE=x\n\
49-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
50 .pyc extension\n\
51-q : don't print version and copyright messages on interactive startup\n\
52-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
53-S : don't imply 'import site' on initialization\n\
54";
55static const char usage_3[] = "\
56-u : force the stdout and stderr streams to be unbuffered;\n\
57 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
58-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
59 can be supplied multiple times to increase verbosity\n\
60-V : print the Python version number and exit (also --version)\n\
61 when given twice, print more information about the build\n\
62-W arg : warning control; arg is action:message:category:module:lineno\n\
63 also PYTHONWARNINGS=arg\n\
64-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
65-X opt : set implementation-specific option\n\
66--check-hash-based-pycs always|default|never:\n\
67 control how Python invalidates hash-based .pyc files\n\
68";
69static const char usage_4[] = "\
70file : program read from script file\n\
71- : program read from stdin (default; interactive mode if a tty)\n\
72arg ...: arguments passed to program in sys.argv[1:]\n\n\
73Other environment variables:\n\
74PYTHONSTARTUP: file executed on interactive startup (no default)\n\
75PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
76 default module search path. The result is sys.path.\n\
77";
78static const char usage_5[] =
79"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
80" The default module search path uses %s.\n"
81"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
82"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
83"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
84static const char usage_6[] =
85"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
86" to seed the hashes of str, bytes and datetime objects. It can also be\n"
87" set to an integer in the range [0,4294967295] to get hash values with a\n"
88" predictable seed.\n"
89"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
90" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
91" hooks.\n"
92"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
93" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
94" locale coercion and locale compatibility warnings on stderr.\n"
95"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
96" debugger. It can be set to the callable of your debugger of choice.\n"
97"PYTHONDEVMODE: enable the development mode.\n"
98"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
99
100#if defined(MS_WINDOWS)
101# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
102#else
103# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
104#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200105
106
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100107/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200108
Victor Stinner6c785c02018-08-01 17:56:14 +0200109/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
110 stdin and stdout error handler to "surrogateescape". It is equal to
111 -1 by default: unknown, will be set by Py_Main() */
Victor Stinnercab5d072019-05-17 19:01:14 +0200112int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200113int Py_DebugFlag = 0; /* Needed by parser.c */
114int Py_VerboseFlag = 0; /* Needed by import.c */
115int Py_QuietFlag = 0; /* Needed by sysmodule.c */
116int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
117int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
118int Py_OptimizeFlag = 0; /* Needed by compile.c */
119int Py_NoSiteFlag = 0; /* Suppress 'import site' */
120int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
121int Py_FrozenFlag = 0; /* Needed by getpath.c */
122int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
123int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
124int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
125int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
126int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
127int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
128#ifdef MS_WINDOWS
129int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
130int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
131#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200132
133
Victor Stinner1075d162019-03-25 23:19:57 +0100134static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100135_Py_GetGlobalVariablesAsDict(void)
136{
137 PyObject *dict, *obj;
138
139 dict = PyDict_New();
140 if (dict == NULL) {
141 return NULL;
142 }
143
144#define SET_ITEM(KEY, EXPR) \
145 do { \
146 obj = (EXPR); \
147 if (obj == NULL) { \
148 return NULL; \
149 } \
150 int res = PyDict_SetItemString(dict, (KEY), obj); \
151 Py_DECREF(obj); \
152 if (res < 0) { \
153 goto fail; \
154 } \
155 } while (0)
156#define SET_ITEM_INT(VAR) \
157 SET_ITEM(#VAR, PyLong_FromLong(VAR))
158#define FROM_STRING(STR) \
159 ((STR != NULL) ? \
160 PyUnicode_FromString(STR) \
161 : (Py_INCREF(Py_None), Py_None))
162#define SET_ITEM_STR(VAR) \
163 SET_ITEM(#VAR, FROM_STRING(VAR))
164
165 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
166 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
167 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
168 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
169
170 SET_ITEM_INT(Py_UTF8Mode);
171 SET_ITEM_INT(Py_DebugFlag);
172 SET_ITEM_INT(Py_VerboseFlag);
173 SET_ITEM_INT(Py_QuietFlag);
174 SET_ITEM_INT(Py_InteractiveFlag);
175 SET_ITEM_INT(Py_InspectFlag);
176
177 SET_ITEM_INT(Py_OptimizeFlag);
178 SET_ITEM_INT(Py_NoSiteFlag);
179 SET_ITEM_INT(Py_BytesWarningFlag);
180 SET_ITEM_INT(Py_FrozenFlag);
181 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
182 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
183 SET_ITEM_INT(Py_NoUserSiteDirectory);
184 SET_ITEM_INT(Py_UnbufferedStdioFlag);
185 SET_ITEM_INT(Py_HashRandomizationFlag);
186 SET_ITEM_INT(Py_IsolatedFlag);
187
188#ifdef MS_WINDOWS
189 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
190 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
191#endif
192
193 return dict;
194
195fail:
196 Py_DECREF(dict);
197 return NULL;
198
199#undef FROM_STRING
200#undef SET_ITEM
201#undef SET_ITEM_INT
202#undef SET_ITEM_STR
203}
204
205
Victor Stinner871ff772019-05-17 23:54:00 +0200206/* --- _PyInitError ----------------------------------------------- */
207
208_PyInitError _PyInitError_Ok(void)
209{ return _Py_INIT_OK(); }
210
211_PyInitError _PyInitError_Error(const char *err_msg)
212{
213 return (_PyInitError){._type = _Py_INIT_ERR_TYPE_ERROR,
214 .err_msg = err_msg};
215}
216
217_PyInitError _PyInitError_NoMemory(void)
218{ return _PyInitError_Error("memory allocation failed"); }
219
220_PyInitError _PyInitError_Exit(int exitcode)
221{ return _Py_INIT_EXIT(exitcode); }
222
223
224int _PyInitError_IsError(_PyInitError err)
225{ return _Py_INIT_IS_ERROR(err); }
226
227int _PyInitError_IsExit(_PyInitError err)
228{ return _Py_INIT_IS_EXIT(err); }
229
230int _PyInitError_Failed(_PyInitError err)
231{ return _Py_INIT_FAILED(err); }
232
233
Victor Stinner74f65682019-03-15 15:08:05 +0100234/* --- _PyWstrList ------------------------------------------------ */
235
236#ifndef NDEBUG
237int
238_PyWstrList_CheckConsistency(const _PyWstrList *list)
239{
240 assert(list->length >= 0);
241 if (list->length != 0) {
242 assert(list->items != NULL);
243 }
244 for (Py_ssize_t i = 0; i < list->length; i++) {
245 assert(list->items[i] != NULL);
246 }
247 return 1;
248}
249#endif /* Py_DEBUG */
250
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100251
Victor Stinner6c785c02018-08-01 17:56:14 +0200252void
Victor Stinner74f65682019-03-15 15:08:05 +0100253_PyWstrList_Clear(_PyWstrList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200254{
Victor Stinner74f65682019-03-15 15:08:05 +0100255 assert(_PyWstrList_CheckConsistency(list));
256 for (Py_ssize_t i=0; i < list->length; i++) {
257 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200258 }
Victor Stinner74f65682019-03-15 15:08:05 +0100259 PyMem_RawFree(list->items);
260 list->length = 0;
261 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200262}
263
264
Victor Stinner74f65682019-03-15 15:08:05 +0100265int
266_PyWstrList_Copy(_PyWstrList *list, const _PyWstrList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200267{
Victor Stinner74f65682019-03-15 15:08:05 +0100268 assert(_PyWstrList_CheckConsistency(list));
269 assert(_PyWstrList_CheckConsistency(list2));
270
271 if (list2->length == 0) {
272 _PyWstrList_Clear(list);
273 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300274 }
Victor Stinner74f65682019-03-15 15:08:05 +0100275
276 _PyWstrList copy = _PyWstrList_INIT;
277
278 size_t size = list2->length * sizeof(list2->items[0]);
279 copy.items = PyMem_RawMalloc(size);
280 if (copy.items == NULL) {
281 return -1;
282 }
283
284 for (Py_ssize_t i=0; i < list2->length; i++) {
285 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
286 if (item == NULL) {
287 _PyWstrList_Clear(&copy);
288 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200289 }
Victor Stinner74f65682019-03-15 15:08:05 +0100290 copy.items[i] = item;
291 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200292 }
Victor Stinner74f65682019-03-15 15:08:05 +0100293
294 _PyWstrList_Clear(list);
295 *list = copy;
296 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200297}
298
299
Victor Stinner74f65682019-03-15 15:08:05 +0100300int
301_PyWstrList_Append(_PyWstrList *list, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100302{
Victor Stinner74f65682019-03-15 15:08:05 +0100303 if (list->length == PY_SSIZE_T_MAX) {
304 /* lenght+1 would overflow */
305 return -1;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100306 }
307
Victor Stinner74f65682019-03-15 15:08:05 +0100308 wchar_t *item2 = _PyMem_RawWcsdup(item);
309 if (item2 == NULL) {
310 return -1;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100311 }
Victor Stinner74f65682019-03-15 15:08:05 +0100312
313 size_t size = (list->length + 1) * sizeof(list->items[0]);
314 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
315 if (items2 == NULL) {
316 PyMem_RawFree(item2);
317 return -1;
318 }
319
320 items2[list->length] = item2;
321 list->items = items2;
322 list->length++;
323 return 0;
324}
325
326
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100327int
Victor Stinner74f65682019-03-15 15:08:05 +0100328_PyWstrList_Extend(_PyWstrList *list, const _PyWstrList *list2)
329{
330 for (Py_ssize_t i = 0; i < list2->length; i++) {
331 if (_PyWstrList_Append(list, list2->items[i])) {
332 return -1;
333 }
334 }
335 return 0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100336}
337
338
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100339static int
340_PyWstrList_Find(_PyWstrList *list, const wchar_t *item)
341{
342 for (Py_ssize_t i = 0; i < list->length; i++) {
343 if (wcscmp(list->items[i], item) == 0) {
344 return 1;
345 }
346 }
347 return 0;
348}
349
350
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100351PyObject*
Victor Stinner74f65682019-03-15 15:08:05 +0100352_PyWstrList_AsList(const _PyWstrList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100353{
Victor Stinner74f65682019-03-15 15:08:05 +0100354 assert(_PyWstrList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100355
Victor Stinner74f65682019-03-15 15:08:05 +0100356 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100357 if (pylist == NULL) {
358 return NULL;
359 }
360
Victor Stinner74f65682019-03-15 15:08:05 +0100361 for (Py_ssize_t i = 0; i < list->length; i++) {
362 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
363 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100364 Py_DECREF(pylist);
365 return NULL;
366 }
Victor Stinner74f65682019-03-15 15:08:05 +0100367 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100368 }
369 return pylist;
370}
371
372
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100373/* --- Py_SetStandardStreamEncoding() ----------------------------- */
374
Victor Stinner124b9eb2018-08-29 01:29:06 +0200375/* Helper to allow an embedding application to override the normal
376 * mechanism that attempts to figure out an appropriate IO encoding
377 */
378
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200379static char *_Py_StandardStreamEncoding = NULL;
380static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200381
382int
383Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
384{
385 if (Py_IsInitialized()) {
386 /* This is too late to have any effect */
387 return -1;
388 }
389
390 int res = 0;
391
392 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
393 but Py_Initialize() can change the allocator. Use a known allocator
394 to be able to release the memory later. */
395 PyMemAllocatorEx old_alloc;
396 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
397
398 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
399 * initialised yet.
400 *
401 * However, the raw memory allocators are initialised appropriately
402 * as C static variables, so _PyMem_RawStrdup is OK even though
403 * Py_Initialize hasn't been called yet.
404 */
405 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200406 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200407 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
408 if (!_Py_StandardStreamEncoding) {
409 res = -2;
410 goto done;
411 }
412 }
413 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200414 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200415 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
416 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200417 PyMem_RawFree(_Py_StandardStreamEncoding);
418 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200419 res = -3;
420 goto done;
421 }
422 }
423#ifdef MS_WINDOWS
424 if (_Py_StandardStreamEncoding) {
425 /* Overriding the stream encoding implies legacy streams */
426 Py_LegacyWindowsStdioFlag = 1;
427 }
428#endif
429
430done:
431 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
432
433 return res;
434}
435
436
437void
438_Py_ClearStandardStreamEncoding(void)
439{
440 /* Use the same allocator than Py_SetStandardStreamEncoding() */
441 PyMemAllocatorEx old_alloc;
442 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
443
444 /* We won't need them anymore. */
445 if (_Py_StandardStreamEncoding) {
446 PyMem_RawFree(_Py_StandardStreamEncoding);
447 _Py_StandardStreamEncoding = NULL;
448 }
449 if (_Py_StandardStreamErrors) {
450 PyMem_RawFree(_Py_StandardStreamErrors);
451 _Py_StandardStreamErrors = NULL;
452 }
453
454 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
455}
456
457
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100458/* --- Py_GetArgcArgv() ------------------------------------------- */
459
460/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner74f65682019-03-15 15:08:05 +0100461static _PyWstrList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100462
463
464void
465_Py_ClearArgcArgv(void)
466{
467 PyMemAllocatorEx old_alloc;
468 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
469
Victor Stinner74f65682019-03-15 15:08:05 +0100470 _PyWstrList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100471
472 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
473}
474
475
Victor Stinner4fffd382019-03-06 01:44:31 +0100476static int
Victor Stinner74f65682019-03-15 15:08:05 +0100477_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100478{
Victor Stinner74f65682019-03-15 15:08:05 +0100479 const _PyWstrList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100480 int res;
481
482 PyMemAllocatorEx old_alloc;
483 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
484
Victor Stinner74f65682019-03-15 15:08:05 +0100485 res = _PyWstrList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100486
487 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
488 return res;
489}
490
491
492/* Make the *original* argc/argv available to other modules.
493 This is rare, but it is needed by the secureware extension. */
494void
495Py_GetArgcArgv(int *argc, wchar_t ***argv)
496{
Victor Stinner74f65682019-03-15 15:08:05 +0100497 *argc = (int)orig_argv.length;
498 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100499}
500
501
502/* --- _PyCoreConfig ---------------------------------------------- */
503
504#define DECODE_LOCALE_ERR(NAME, LEN) \
505 (((LEN) == -2) \
Victor Stinnerdb719752019-05-01 05:35:33 +0200506 ? _Py_INIT_ERR("cannot decode " NAME) \
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100507 : _Py_INIT_NO_MEMORY())
508
Victor Stinner6c785c02018-08-01 17:56:14 +0200509/* Free memory allocated in config, but don't clear all attributes */
510void
511_PyCoreConfig_Clear(_PyCoreConfig *config)
512{
513#define CLEAR(ATTR) \
514 do { \
515 PyMem_RawFree(ATTR); \
516 ATTR = NULL; \
517 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200518
519 CLEAR(config->pycache_prefix);
520 CLEAR(config->module_search_path_env);
521 CLEAR(config->home);
522 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200523
Victor Stinner74f65682019-03-15 15:08:05 +0100524 _PyWstrList_Clear(&config->argv);
525 _PyWstrList_Clear(&config->warnoptions);
526 _PyWstrList_Clear(&config->xoptions);
527 _PyWstrList_Clear(&config->module_search_paths);
528 config->use_module_search_paths = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200529
530 CLEAR(config->executable);
531 CLEAR(config->prefix);
532 CLEAR(config->base_prefix);
533 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200534 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200535
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200536 CLEAR(config->filesystem_encoding);
537 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200538 CLEAR(config->stdio_encoding);
539 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100540 CLEAR(config->run_command);
541 CLEAR(config->run_module);
542 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400543 CLEAR(config->check_hash_pycs_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200544#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200545}
546
547
Victor Stinnercab5d072019-05-17 19:01:14 +0200548void
549_PyCoreConfig_Init(_PyCoreConfig *config)
550{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200551 memset(config, 0, sizeof(*config));
552
553 config->_config_version = _Py_CONFIG_VERSION;
554 config->isolated = -1;
555 config->use_environment = -1;
556 config->dev_mode = -1;
557 config->install_signal_handlers = 1;
558 config->use_hash_seed = -1;
559 config->faulthandler = -1;
560 config->tracemalloc = -1;
561 config->use_module_search_paths = 0;
562 config->parse_argv = 0;
563 config->site_import = -1;
564 config->bytes_warning = -1;
565 config->inspect = -1;
566 config->interactive = -1;
567 config->optimization_level = -1;
568 config->parser_debug= -1;
569 config->write_bytecode = -1;
570 config->verbose = -1;
571 config->quiet = -1;
572 config->user_site_directory = -1;
573 config->configure_c_stdio = 0;
574 config->buffered_stdio = -1;
575 config->_install_importlib = 1;
576 config->check_hash_pycs_mode = NULL;
577 config->pathconfig_warnings = -1;
578 config->_init_main = 1;
579#ifdef MS_WINDOWS
580 config->legacy_windows_stdio = -1;
581#endif
582}
583
584
585static void
586_PyCoreConfig_InitDefaults(_PyCoreConfig *config)
587{
588 _PyCoreConfig_Init(config);
589
590 config->isolated = 0;
591 config->use_environment = 1;
592 config->site_import = 1;
593 config->bytes_warning = 0;
594 config->inspect = 0;
595 config->interactive = 0;
596 config->optimization_level = 0;
597 config->parser_debug= 0;
598 config->write_bytecode = 1;
599 config->verbose = 0;
600 config->quiet = 0;
601 config->user_site_directory = 1;
602 config->buffered_stdio = 1;
603 config->pathconfig_warnings = 1;
604#ifdef MS_WINDOWS
605 config->legacy_windows_stdio = 0;
606#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200607}
608
609
610_PyInitError
611_PyCoreConfig_InitPythonConfig(_PyCoreConfig *config)
612{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200613 _PyCoreConfig_InitDefaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200614
615 config->configure_c_stdio = 1;
616 config->parse_argv = 1;
617
618 return _Py_INIT_OK();
619}
620
621
622_PyInitError
623_PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config)
624{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200625 _PyCoreConfig_InitDefaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200626
Victor Stinnercab5d072019-05-17 19:01:14 +0200627 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200628 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200629 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200630 config->dev_mode = 0;
631 config->install_signal_handlers = 0;
632 config->use_hash_seed = 0;
633 config->faulthandler = 0;
634 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200635 config->pathconfig_warnings = 0;
636#ifdef MS_WINDOWS
637 config->legacy_windows_stdio = 0;
638#endif
639
640 return _Py_INIT_OK();
641}
642
643
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200644/* Copy str into *config_str (duplicate the string) */
645_PyInitError
Victor Stinner709d23d2019-05-02 14:56:30 -0400646_PyCoreConfig_SetString(wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200647{
648 wchar_t *str2;
649 if (str != NULL) {
650 str2 = _PyMem_RawWcsdup(str);
651 if (str2 == NULL) {
652 return _Py_INIT_NO_MEMORY();
653 }
654 }
655 else {
656 str2 = NULL;
657 }
658 PyMem_RawFree(*config_str);
659 *config_str = str2;
660 return _Py_INIT_OK();
661}
662
663
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200664static _PyInitError
Victor Stinner709d23d2019-05-02 14:56:30 -0400665_PyCoreConfig_DecodeLocaleErr(wchar_t **config_str, const char *str,
666 const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200667{
Victor Stinner70005ac2019-05-02 15:25:34 -0400668 _PyInitError err = _Py_PreInitialize(NULL);
669 if (_Py_INIT_FAILED(err)) {
670 return err;
671 }
672
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200673 wchar_t *str2;
674 if (str != NULL) {
675 size_t len;
676 str2 = Py_DecodeLocale(str, &len);
677 if (str2 == NULL) {
678 if (len == (size_t)-2) {
679 return _Py_INIT_ERR(decode_err_msg);
680 }
681 else {
682 return _Py_INIT_NO_MEMORY();
683 }
684 }
685 }
686 else {
687 str2 = NULL;
688 }
689 PyMem_RawFree(*config_str);
690 *config_str = str2;
691 return _Py_INIT_OK();
692}
693
694
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200695#define CONFIG_DECODE_LOCALE(config_str, str, NAME) \
Victor Stinner709d23d2019-05-02 14:56:30 -0400696 _PyCoreConfig_DecodeLocaleErr(config_str, str, "cannot decode " NAME)
697
698
Victor Stinner70005ac2019-05-02 15:25:34 -0400699/* Decode str using Py_DecodeLocale() and set the result into *config_str.
700 Pre-initialize Python if needed to ensure that encodings are properly
701 configured. */
Victor Stinner709d23d2019-05-02 14:56:30 -0400702_PyInitError
703_PyCoreConfig_DecodeLocale(wchar_t **config_str, const char *str)
704{
705 return CONFIG_DECODE_LOCALE(config_str, str, "string");
706}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200707
708
709_PyInitError
Victor Stinner6c785c02018-08-01 17:56:14 +0200710_PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
711{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200712 _PyInitError err;
Victor Stinner6c785c02018-08-01 17:56:14 +0200713 _PyCoreConfig_Clear(config);
714
715#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200716#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200717 do { \
Victor Stinner709d23d2019-05-02 14:56:30 -0400718 err = _PyCoreConfig_SetString(&config->ATTR, config2->ATTR); \
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200719 if (_Py_INIT_FAILED(err)) { \
720 return err; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200721 } \
722 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100723#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200724 do { \
Victor Stinner74f65682019-03-15 15:08:05 +0100725 if (_PyWstrList_Copy(&config->LIST, &config2->LIST) < 0 ) { \
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200726 return _Py_INIT_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200727 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200728 } while (0)
729
Victor Stinner20004952019-03-26 02:31:11 +0100730 COPY_ATTR(isolated);
731 COPY_ATTR(use_environment);
732 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200733 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200734 COPY_ATTR(use_hash_seed);
735 COPY_ATTR(hash_seed);
736 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200737 COPY_ATTR(faulthandler);
738 COPY_ATTR(tracemalloc);
739 COPY_ATTR(import_time);
740 COPY_ATTR(show_ref_count);
741 COPY_ATTR(show_alloc_count);
742 COPY_ATTR(dump_refs);
743 COPY_ATTR(malloc_stats);
744
Victor Stinner124b9eb2018-08-29 01:29:06 +0200745 COPY_WSTR_ATTR(pycache_prefix);
746 COPY_WSTR_ATTR(module_search_path_env);
747 COPY_WSTR_ATTR(home);
748 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200749
Victor Stinnerae239f62019-05-16 17:02:56 +0200750 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100751 COPY_WSTRLIST(argv);
752 COPY_WSTRLIST(warnoptions);
753 COPY_WSTRLIST(xoptions);
754 COPY_WSTRLIST(module_search_paths);
755 COPY_ATTR(use_module_search_paths);
Victor Stinner6c785c02018-08-01 17:56:14 +0200756
Victor Stinner124b9eb2018-08-29 01:29:06 +0200757 COPY_WSTR_ATTR(executable);
758 COPY_WSTR_ATTR(prefix);
759 COPY_WSTR_ATTR(base_prefix);
760 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200761 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200762
Victor Stinner6c785c02018-08-01 17:56:14 +0200763 COPY_ATTR(site_import);
764 COPY_ATTR(bytes_warning);
765 COPY_ATTR(inspect);
766 COPY_ATTR(interactive);
767 COPY_ATTR(optimization_level);
768 COPY_ATTR(parser_debug);
769 COPY_ATTR(write_bytecode);
770 COPY_ATTR(verbose);
771 COPY_ATTR(quiet);
772 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200773 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200774 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400775 COPY_WSTR_ATTR(filesystem_encoding);
776 COPY_WSTR_ATTR(filesystem_errors);
777 COPY_WSTR_ATTR(stdio_encoding);
778 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200779#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200780 COPY_ATTR(legacy_windows_stdio);
781#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100782 COPY_ATTR(skip_source_first_line);
783 COPY_WSTR_ATTR(run_command);
784 COPY_WSTR_ATTR(run_module);
785 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400786 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200787 COPY_ATTR(pathconfig_warnings);
788 COPY_ATTR(_init_main);
Victor Stinner6c785c02018-08-01 17:56:14 +0200789
790#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200791#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200792#undef COPY_WSTRLIST
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200793 return _Py_INIT_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200794}
795
796
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100797static PyObject *
798_PyCoreConfig_AsDict(const _PyCoreConfig *config)
799{
800 PyObject *dict;
801
802 dict = PyDict_New();
803 if (dict == NULL) {
804 return NULL;
805 }
806
807#define SET_ITEM(KEY, EXPR) \
808 do { \
809 PyObject *obj = (EXPR); \
810 if (obj == NULL) { \
811 goto fail; \
812 } \
813 int res = PyDict_SetItemString(dict, (KEY), obj); \
814 Py_DECREF(obj); \
815 if (res < 0) { \
816 goto fail; \
817 } \
818 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100819#define SET_ITEM_INT(ATTR) \
820 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
821#define SET_ITEM_UINT(ATTR) \
822 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100823#define FROM_WSTRING(STR) \
824 ((STR != NULL) ? \
825 PyUnicode_FromWideChar(STR, -1) \
826 : (Py_INCREF(Py_None), Py_None))
827#define SET_ITEM_WSTR(ATTR) \
828 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
829#define SET_ITEM_WSTRLIST(LIST) \
830 SET_ITEM(#LIST, _PyWstrList_AsList(&config->LIST))
831
832 SET_ITEM_INT(isolated);
833 SET_ITEM_INT(use_environment);
834 SET_ITEM_INT(dev_mode);
835 SET_ITEM_INT(install_signal_handlers);
836 SET_ITEM_INT(use_hash_seed);
837 SET_ITEM_UINT(hash_seed);
838 SET_ITEM_INT(faulthandler);
839 SET_ITEM_INT(tracemalloc);
840 SET_ITEM_INT(import_time);
841 SET_ITEM_INT(show_ref_count);
842 SET_ITEM_INT(show_alloc_count);
843 SET_ITEM_INT(dump_refs);
844 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400845 SET_ITEM_WSTR(filesystem_encoding);
846 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100847 SET_ITEM_WSTR(pycache_prefix);
848 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200849 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100850 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100851 SET_ITEM_WSTRLIST(xoptions);
852 SET_ITEM_WSTRLIST(warnoptions);
853 SET_ITEM_WSTR(module_search_path_env);
854 SET_ITEM_WSTR(home);
855 SET_ITEM_WSTRLIST(module_search_paths);
856 SET_ITEM_WSTR(executable);
857 SET_ITEM_WSTR(prefix);
858 SET_ITEM_WSTR(base_prefix);
859 SET_ITEM_WSTR(exec_prefix);
860 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100861 SET_ITEM_INT(site_import);
862 SET_ITEM_INT(bytes_warning);
863 SET_ITEM_INT(inspect);
864 SET_ITEM_INT(interactive);
865 SET_ITEM_INT(optimization_level);
866 SET_ITEM_INT(parser_debug);
867 SET_ITEM_INT(write_bytecode);
868 SET_ITEM_INT(verbose);
869 SET_ITEM_INT(quiet);
870 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200871 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100872 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400873 SET_ITEM_WSTR(stdio_encoding);
874 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100875#ifdef MS_WINDOWS
876 SET_ITEM_INT(legacy_windows_stdio);
877#endif
878 SET_ITEM_INT(skip_source_first_line);
879 SET_ITEM_WSTR(run_command);
880 SET_ITEM_WSTR(run_module);
881 SET_ITEM_WSTR(run_filename);
882 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400883 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200884 SET_ITEM_INT(pathconfig_warnings);
885 SET_ITEM_INT(_init_main);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100886
887 return dict;
888
889fail:
890 Py_DECREF(dict);
891 return NULL;
892
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100893#undef FROM_WSTRING
894#undef SET_ITEM
895#undef SET_ITEM_INT
896#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100897#undef SET_ITEM_WSTR
898#undef SET_ITEM_WSTRLIST
899}
900
901
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100902static const char*
Victor Stinner6c785c02018-08-01 17:56:14 +0200903_PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name)
904{
Victor Stinner20004952019-03-26 02:31:11 +0100905 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200906}
907
908
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100909/* Get a copy of the environment variable as wchar_t*.
910 Return 0 on success, but *dest can be NULL.
911 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200912static _PyInitError
Victor Stinner6c785c02018-08-01 17:56:14 +0200913_PyCoreConfig_GetEnvDup(const _PyCoreConfig *config,
914 wchar_t **dest,
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200915 wchar_t *wname, char *name,
916 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200917{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200918 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100919 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200920
Victor Stinner20004952019-03-26 02:31:11 +0100921 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200922 *dest = NULL;
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200923 return _Py_INIT_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200924 }
925
926#ifdef MS_WINDOWS
927 const wchar_t *var = _wgetenv(wname);
928 if (!var || var[0] == '\0') {
929 *dest = NULL;
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200930 return _Py_INIT_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200931 }
932
Victor Stinner709d23d2019-05-02 14:56:30 -0400933 return _PyCoreConfig_SetString(dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +0200934#else
935 const char *var = getenv(name);
936 if (!var || var[0] == '\0') {
937 *dest = NULL;
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200938 return _Py_INIT_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200939 }
940
Victor Stinner709d23d2019-05-02 14:56:30 -0400941 return _PyCoreConfig_DecodeLocaleErr(dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +0200942#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200943}
944
945
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200946#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
947 _PyCoreConfig_GetEnvDup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
948
949
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100950static void
Victor Stinner6c785c02018-08-01 17:56:14 +0200951_PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
952{
953#define COPY_FLAG(ATTR, VALUE) \
954 if (config->ATTR == -1) { \
955 config->ATTR = VALUE; \
956 }
957#define COPY_NOT_FLAG(ATTR, VALUE) \
958 if (config->ATTR == -1) { \
959 config->ATTR = !(VALUE); \
960 }
961
Victor Stinner20004952019-03-26 02:31:11 +0100962 COPY_FLAG(isolated, Py_IsolatedFlag);
963 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +0200964 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
965 COPY_FLAG(inspect, Py_InspectFlag);
966 COPY_FLAG(interactive, Py_InteractiveFlag);
967 COPY_FLAG(optimization_level, Py_OptimizeFlag);
968 COPY_FLAG(parser_debug, Py_DebugFlag);
969 COPY_FLAG(verbose, Py_VerboseFlag);
970 COPY_FLAG(quiet, Py_QuietFlag);
971#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200972 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
973#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200974 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +0200975
Victor Stinner6c785c02018-08-01 17:56:14 +0200976 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
977 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
978 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
979 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
980
Victor Stinner6c785c02018-08-01 17:56:14 +0200981#undef COPY_FLAG
982#undef COPY_NOT_FLAG
983}
984
985
986/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100987static void
Victor Stinner6c785c02018-08-01 17:56:14 +0200988_PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
989{
990#define COPY_FLAG(ATTR, VAR) \
991 if (config->ATTR != -1) { \
992 VAR = config->ATTR; \
993 }
994#define COPY_NOT_FLAG(ATTR, VAR) \
995 if (config->ATTR != -1) { \
996 VAR = !config->ATTR; \
997 }
998
Victor Stinner20004952019-03-26 02:31:11 +0100999 COPY_FLAG(isolated, Py_IsolatedFlag);
1000 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001001 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1002 COPY_FLAG(inspect, Py_InspectFlag);
1003 COPY_FLAG(interactive, Py_InteractiveFlag);
1004 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1005 COPY_FLAG(parser_debug, Py_DebugFlag);
1006 COPY_FLAG(verbose, Py_VerboseFlag);
1007 COPY_FLAG(quiet, Py_QuietFlag);
1008#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001009 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1010#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001011 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001012
Victor Stinner6c785c02018-08-01 17:56:14 +02001013 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1014 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1015 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1016 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1017
Victor Stinner6c785c02018-08-01 17:56:14 +02001018 /* Random or non-zero hash seed */
1019 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1020 config->hash_seed != 0);
1021
1022#undef COPY_FLAG
1023#undef COPY_NOT_FLAG
1024}
1025
1026
1027/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1028 environment variables on macOS if available. */
1029static _PyInitError
1030config_init_program_name(_PyCoreConfig *config)
1031{
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001032 _PyInitError err;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001033
Victor Stinner6c785c02018-08-01 17:56:14 +02001034 /* If Py_SetProgramName() was called, use its value */
1035 const wchar_t *program_name = _Py_path_config.program_name;
1036 if (program_name != NULL) {
1037 config->program_name = _PyMem_RawWcsdup(program_name);
1038 if (config->program_name == NULL) {
1039 return _Py_INIT_NO_MEMORY();
1040 }
1041 return _Py_INIT_OK();
1042 }
1043
1044#ifdef __APPLE__
1045 /* On MacOS X, when the Python interpreter is embedded in an
1046 application bundle, it gets executed by a bootstrapping script
1047 that does os.execve() with an argv[0] that's different from the
1048 actual Python executable. This is needed to keep the Finder happy,
1049 or rather, to work around Apple's overly strict requirements of
1050 the process name. However, we still need a usable sys.executable,
1051 so the actual executable path is passed in an environment variable.
1052 See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
1053 script. */
1054 const char *p = _PyCoreConfig_GetEnv(config, "PYTHONEXECUTABLE");
1055 if (p != NULL) {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001056 err = CONFIG_DECODE_LOCALE(&config->program_name, p,
1057 "PYTHONEXECUTABLE environment variable");
1058 if (_Py_INIT_FAILED(err)) {
1059 return err;
Victor Stinner6c785c02018-08-01 17:56:14 +02001060 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001061 return _Py_INIT_OK();
1062 }
1063#ifdef WITH_NEXT_FRAMEWORK
1064 else {
1065 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1066 if (pyvenv_launcher && *pyvenv_launcher) {
1067 /* Used by Mac/Tools/pythonw.c to forward
1068 * the argv0 of the stub executable
1069 */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001070 err = CONFIG_DECODE_LOCALE(&config->program_name, pyvenv_launcher,
1071 "__PYVENV_LAUNCHER__ environment variable");
1072 if (_Py_INIT_FAILED(err)) {
1073 return err;
Victor Stinner6c785c02018-08-01 17:56:14 +02001074 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001075 return _Py_INIT_OK();
1076 }
1077 }
1078#endif /* WITH_NEXT_FRAMEWORK */
1079#endif /* __APPLE__ */
1080
Victor Stinnerfed02e12019-05-17 11:12:09 +02001081 /* Use argv[0] if available and non-empty */
1082 const _PyWstrList *argv = &config->argv;
1083 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1084 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1085 if (config->program_name == NULL) {
1086 return _Py_INIT_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001087 }
1088 return _Py_INIT_OK();
1089 }
1090
Victor Stinnerfed02e12019-05-17 11:12:09 +02001091 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001092#ifdef MS_WINDOWS
1093 const wchar_t *default_program_name = L"python";
1094#else
1095 const wchar_t *default_program_name = L"python3";
1096#endif
Victor Stinner709d23d2019-05-02 14:56:30 -04001097 err = _PyCoreConfig_SetString(&config->program_name, default_program_name);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001098 if (_Py_INIT_FAILED(err)) {
1099 return err;
Victor Stinner6c785c02018-08-01 17:56:14 +02001100 }
1101 return _Py_INIT_OK();
1102}
1103
Steve Dower177a41a2018-11-17 20:41:48 -08001104static _PyInitError
1105config_init_executable(_PyCoreConfig *config)
1106{
1107 assert(config->executable == NULL);
1108
1109 /* If Py_SetProgramFullPath() was called, use its value */
1110 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1111 if (program_full_path != NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001112 _PyInitError err = _PyCoreConfig_SetString(&config->executable,
1113 program_full_path);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001114 if (_Py_INIT_FAILED(err)) {
1115 return err;
Steve Dower177a41a2018-11-17 20:41:48 -08001116 }
1117 return _Py_INIT_OK();
1118 }
Steve Dower177a41a2018-11-17 20:41:48 -08001119 return _Py_INIT_OK();
1120}
Victor Stinner6c785c02018-08-01 17:56:14 +02001121
Victor Stinner4fffd382019-03-06 01:44:31 +01001122
Victor Stinner6c785c02018-08-01 17:56:14 +02001123static const wchar_t*
1124config_get_xoption(const _PyCoreConfig *config, wchar_t *name)
1125{
Victor Stinner74f65682019-03-15 15:08:05 +01001126 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001127}
1128
1129
1130static _PyInitError
1131config_init_home(_PyCoreConfig *config)
1132{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001133 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001134
1135 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001136 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001137 if (home) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001138 _PyInitError err = _PyCoreConfig_SetString(&config->home, home);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001139 if (_Py_INIT_FAILED(err)) {
1140 return err;
Victor Stinner6c785c02018-08-01 17:56:14 +02001141 }
1142 return _Py_INIT_OK();
1143 }
1144
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001145 return CONFIG_GET_ENV_DUP(config, &config->home,
1146 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001147}
1148
1149
1150static _PyInitError
1151config_init_hash_seed(_PyCoreConfig *config)
1152{
1153 const char *seed_text = _PyCoreConfig_GetEnv(config, "PYTHONHASHSEED");
1154
1155 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1156 /* Convert a text seed to a numeric one */
1157 if (seed_text && strcmp(seed_text, "random") != 0) {
1158 const char *endptr = seed_text;
1159 unsigned long seed;
1160 errno = 0;
1161 seed = strtoul(seed_text, (char **)&endptr, 10);
1162 if (*endptr != '\0'
1163 || seed > 4294967295UL
1164 || (errno == ERANGE && seed == ULONG_MAX))
1165 {
Victor Stinnerdb719752019-05-01 05:35:33 +02001166 return _Py_INIT_ERR("PYTHONHASHSEED must be \"random\" "
1167 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001168 }
1169 /* Use a specific hash */
1170 config->use_hash_seed = 1;
1171 config->hash_seed = seed;
1172 }
1173 else {
1174 /* Use a random hash */
1175 config->use_hash_seed = 0;
1176 config->hash_seed = 0;
1177 }
1178 return _Py_INIT_OK();
1179}
1180
1181
Victor Stinner6c785c02018-08-01 17:56:14 +02001182static int
1183config_wstr_to_int(const wchar_t *wstr, int *result)
1184{
1185 const wchar_t *endptr = wstr;
1186 errno = 0;
1187 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1188 if (*endptr != '\0' || errno == ERANGE) {
1189 return -1;
1190 }
1191 if (value < INT_MIN || value > INT_MAX) {
1192 return -1;
1193 }
1194
1195 *result = (int)value;
1196 return 0;
1197}
1198
1199
Victor Stinner6c785c02018-08-01 17:56:14 +02001200static _PyInitError
1201config_read_env_vars(_PyCoreConfig *config)
1202{
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001203 _PyInitError err;
Victor Stinner20004952019-03-26 02:31:11 +01001204 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001205
Victor Stinner6c785c02018-08-01 17:56:14 +02001206 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001207 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1208 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1209 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1210 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001211
1212 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001213 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001214 if (dont_write_bytecode) {
1215 config->write_bytecode = 0;
1216 }
1217
1218 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001219 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001220 if (no_user_site_directory) {
1221 config->user_site_directory = 0;
1222 }
1223
1224 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001225 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001226 if (unbuffered_stdio) {
1227 config->buffered_stdio = 0;
1228 }
1229
1230#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001231 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001232 "PYTHONLEGACYWINDOWSSTDIO");
1233#endif
1234
Victor Stinner6c785c02018-08-01 17:56:14 +02001235 if (_PyCoreConfig_GetEnv(config, "PYTHONDUMPREFS")) {
1236 config->dump_refs = 1;
1237 }
1238 if (_PyCoreConfig_GetEnv(config, "PYTHONMALLOCSTATS")) {
1239 config->malloc_stats = 1;
1240 }
1241
Victor Stinner4a1468e2019-03-20 03:11:38 +01001242 if (config->module_search_path_env == NULL) {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001243 err = CONFIG_GET_ENV_DUP(config, &config->module_search_path_env,
1244 L"PYTHONPATH", "PYTHONPATH");
1245 if (_Py_INIT_FAILED(err)) {
1246 return err;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001247 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001248 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001249
1250 if (config->use_hash_seed < 0) {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001251 err = config_init_hash_seed(config);
Victor Stinner6c785c02018-08-01 17:56:14 +02001252 if (_Py_INIT_FAILED(err)) {
1253 return err;
1254 }
1255 }
1256
1257 return _Py_INIT_OK();
1258}
1259
1260
1261static _PyInitError
1262config_init_tracemalloc(_PyCoreConfig *config)
1263{
1264 int nframe;
1265 int valid;
1266
1267 const char *env = _PyCoreConfig_GetEnv(config, "PYTHONTRACEMALLOC");
1268 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001269 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001270 valid = (nframe >= 0);
1271 }
1272 else {
1273 valid = 0;
1274 }
1275 if (!valid) {
Victor Stinnerdb719752019-05-01 05:35:33 +02001276 return _Py_INIT_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001277 }
1278 config->tracemalloc = nframe;
1279 }
1280
1281 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1282 if (xoption) {
1283 const wchar_t *sep = wcschr(xoption, L'=');
1284 if (sep) {
1285 if (!config_wstr_to_int(sep + 1, &nframe)) {
1286 valid = (nframe >= 0);
1287 }
1288 else {
1289 valid = 0;
1290 }
1291 if (!valid) {
Victor Stinnerdb719752019-05-01 05:35:33 +02001292 return _Py_INIT_ERR("-X tracemalloc=NFRAME: "
1293 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001294 }
1295 }
1296 else {
1297 /* -X tracemalloc behaves as -X tracemalloc=1 */
1298 nframe = 1;
1299 }
1300 config->tracemalloc = nframe;
1301 }
1302 return _Py_INIT_OK();
1303}
1304
1305
1306static _PyInitError
1307config_init_pycache_prefix(_PyCoreConfig *config)
1308{
1309 assert(config->pycache_prefix == NULL);
1310
1311 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1312 if (xoption) {
1313 const wchar_t *sep = wcschr(xoption, L'=');
1314 if (sep && wcslen(sep) > 1) {
1315 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1316 if (config->pycache_prefix == NULL) {
1317 return _Py_INIT_NO_MEMORY();
1318 }
1319 }
1320 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001321 // PYTHONPYCACHEPREFIX env var ignored
1322 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001323 config->pycache_prefix = NULL;
1324 }
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001325 return _Py_INIT_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001326 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001327
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001328 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1329 L"PYTHONPYCACHEPREFIX",
1330 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001331}
1332
1333
1334static _PyInitError
1335config_read_complex_options(_PyCoreConfig *config)
1336{
1337 /* More complex options configured by env var and -X option */
1338 if (config->faulthandler < 0) {
1339 if (_PyCoreConfig_GetEnv(config, "PYTHONFAULTHANDLER")
1340 || config_get_xoption(config, L"faulthandler")) {
1341 config->faulthandler = 1;
1342 }
1343 }
1344 if (_PyCoreConfig_GetEnv(config, "PYTHONPROFILEIMPORTTIME")
1345 || config_get_xoption(config, L"importtime")) {
1346 config->import_time = 1;
1347 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001348
1349 _PyInitError err;
1350 if (config->tracemalloc < 0) {
1351 err = config_init_tracemalloc(config);
1352 if (_Py_INIT_FAILED(err)) {
1353 return err;
1354 }
1355 }
1356
1357 if (config->pycache_prefix == NULL) {
1358 err = config_init_pycache_prefix(config);
1359 if (_Py_INIT_FAILED(err)) {
1360 return err;
1361 }
1362 }
1363 return _Py_INIT_OK();
1364}
1365
1366
Victor Stinner709d23d2019-05-02 14:56:30 -04001367static const wchar_t *
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001368config_get_stdio_errors(const _PyCoreConfig *config)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001369{
1370#ifndef MS_WINDOWS
1371 const char *loc = setlocale(LC_CTYPE, NULL);
1372 if (loc != NULL) {
1373 /* surrogateescape is the default in the legacy C and POSIX locales */
1374 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001375 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001376 }
1377
1378#ifdef PY_COERCE_C_LOCALE
1379 /* surrogateescape is the default in locale coercion target locales */
1380 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001381 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001382 }
1383#endif
1384 }
1385
Victor Stinner709d23d2019-05-02 14:56:30 -04001386 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001387#else
1388 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001389 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001390#endif
1391}
1392
1393
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001394static _PyInitError
Victor Stinner709d23d2019-05-02 14:56:30 -04001395config_get_locale_encoding(wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001396{
1397#ifdef MS_WINDOWS
1398 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001399 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner709d23d2019-05-02 14:56:30 -04001400 return _PyCoreConfig_DecodeLocale(locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001401#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner709d23d2019-05-02 14:56:30 -04001402 return _PyCoreConfig_SetString(locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001403#else
1404 const char *encoding = nl_langinfo(CODESET);
1405 if (!encoding || encoding[0] == '\0') {
Victor Stinnerdb719752019-05-01 05:35:33 +02001406 return _Py_INIT_ERR("failed to get the locale encoding: "
1407 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001408 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001409 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
1410 return CONFIG_DECODE_LOCALE(locale_encoding, encoding,
1411 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001412#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001413}
1414
1415
1416static _PyInitError
Victor Stinner20004952019-03-26 02:31:11 +01001417config_init_stdio_encoding(_PyCoreConfig *config,
1418 const _PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001419{
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001420 _PyInitError err;
1421
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001422 /* If Py_SetStandardStreamEncoding() have been called, use these
1423 parameters. */
1424 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001425 err = CONFIG_DECODE_LOCALE(&config->stdio_encoding,
1426 _Py_StandardStreamEncoding,
1427 "_Py_StandardStreamEncoding");
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001428 if (_Py_INIT_FAILED(err)) {
1429 return err;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001430 }
1431 }
1432
1433 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001434 err = CONFIG_DECODE_LOCALE(&config->stdio_errors,
1435 _Py_StandardStreamErrors,
1436 "_Py_StandardStreamErrors");
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001437 if (_Py_INIT_FAILED(err)) {
1438 return err;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001439 }
1440 }
1441
1442 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
1443 return _Py_INIT_OK();
1444 }
1445
1446 /* PYTHONIOENCODING environment variable */
1447 const char *opt = _PyCoreConfig_GetEnv(config, "PYTHONIOENCODING");
1448 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001449 char *pythonioencoding = _PyMem_RawStrdup(opt);
1450 if (pythonioencoding == NULL) {
1451 return _Py_INIT_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001452 }
1453
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001454 char *errors = strchr(pythonioencoding, ':');
1455 if (errors) {
1456 *errors = '\0';
1457 errors++;
1458 if (!errors[0]) {
1459 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001460 }
1461 }
1462
1463 /* Does PYTHONIOENCODING contain an encoding? */
1464 if (pythonioencoding[0]) {
1465 if (config->stdio_encoding == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001466 err = CONFIG_DECODE_LOCALE(&config->stdio_encoding,
1467 pythonioencoding,
1468 "PYTHONIOENCODING environment variable");
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001469 if (_Py_INIT_FAILED(err)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001470 PyMem_RawFree(pythonioencoding);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001471 return err;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001472 }
1473 }
1474
1475 /* If the encoding is set but not the error handler,
1476 use "strict" error handler by default.
1477 PYTHONIOENCODING=latin1 behaves as
1478 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001479 if (!errors) {
1480 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001481 }
1482 }
1483
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001484 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001485 err = CONFIG_DECODE_LOCALE(&config->stdio_errors,
1486 errors,
1487 "PYTHONIOENCODING environment variable");
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001488 if (_Py_INIT_FAILED(err)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001489 PyMem_RawFree(pythonioencoding);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001490 return err;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001491 }
1492 }
1493
1494 PyMem_RawFree(pythonioencoding);
1495 }
1496
1497 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001498 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001499 if (config->stdio_encoding == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001500 err = _PyCoreConfig_SetString(&config->stdio_encoding, L"utf-8");
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001501 if (_Py_INIT_FAILED(err)) {
1502 return err;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001503 }
1504 }
1505 if (config->stdio_errors == NULL) {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001506 err = _PyCoreConfig_SetString(&config->stdio_errors,
Victor Stinner709d23d2019-05-02 14:56:30 -04001507 L"surrogateescape");
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001508 if (_Py_INIT_FAILED(err)) {
1509 return err;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001510 }
1511 }
1512 }
1513
1514 /* Choose the default error handler based on the current locale. */
1515 if (config->stdio_encoding == NULL) {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001516 err = config_get_locale_encoding(&config->stdio_encoding);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001517 if (_Py_INIT_FAILED(err)) {
1518 return err;
1519 }
1520 }
1521 if (config->stdio_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001522 const wchar_t *errors = config_get_stdio_errors(config);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001523 assert(errors != NULL);
1524
1525 err = _PyCoreConfig_SetString(&config->stdio_errors, errors);
1526 if (_Py_INIT_FAILED(err)) {
1527 return err;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001528 }
1529 }
1530
1531 return _Py_INIT_OK();
1532}
1533
1534
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001535static _PyInitError
Victor Stinner20004952019-03-26 02:31:11 +01001536config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001537{
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001538 _PyInitError err;
1539
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001540 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001541#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner709d23d2019-05-02 14:56:30 -04001542 err = _PyCoreConfig_SetString(&config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001543#else
Victor Stinnere2510952019-05-02 11:28:57 -04001544
1545#ifdef MS_WINDOWS
1546 if (preconfig->legacy_windows_fs_encoding) {
1547 /* Legacy Windows filesystem encoding: mbcs/replace */
1548 err = _PyCoreConfig_SetString(&config->filesystem_encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001549 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001550 }
1551 else
1552#endif
Victor Stinner20004952019-03-26 02:31:11 +01001553 if (preconfig->utf8_mode) {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001554 err = _PyCoreConfig_SetString(&config->filesystem_encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001555 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001556 }
Victor Stinnere2510952019-05-02 11:28:57 -04001557#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001558 else if (_Py_GetForceASCII()) {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001559 err = _PyCoreConfig_SetString(&config->filesystem_encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001560 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001561 }
Victor Stinnere2510952019-05-02 11:28:57 -04001562#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001563 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001564#ifdef MS_WINDOWS
1565 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001566 err = _PyCoreConfig_SetString(&config->filesystem_encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001567 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001568#else
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001569 err = config_get_locale_encoding(&config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001570#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001571 }
Victor Stinnere2510952019-05-02 11:28:57 -04001572#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001573
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001574 if (_Py_INIT_FAILED(err)) {
1575 return err;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001576 }
1577 }
1578
1579 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001580 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001581#ifdef MS_WINDOWS
1582 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001583 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001584 }
1585 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001586 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001587 }
1588#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001589 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001590#endif
1591 err = _PyCoreConfig_SetString(&config->filesystem_errors, errors);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001592 if (_Py_INIT_FAILED(err)) {
1593 return err;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001594 }
1595 }
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001596 return _Py_INIT_OK();
1597}
1598
1599
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001600static _PyInitError
Victor Stinner870b0352019-05-17 03:15:12 +02001601config_read(_PyCoreConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001602{
1603 _PyInitError err;
Victor Stinner20004952019-03-26 02:31:11 +01001604 const _PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001605
Victor Stinner20004952019-03-26 02:31:11 +01001606 if (config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001607 err = config_read_env_vars(config);
1608 if (_Py_INIT_FAILED(err)) {
1609 return err;
1610 }
1611 }
1612
1613 /* -X options */
1614 if (config_get_xoption(config, L"showrefcount")) {
1615 config->show_ref_count = 1;
1616 }
1617 if (config_get_xoption(config, L"showalloccount")) {
1618 config->show_alloc_count = 1;
1619 }
1620
1621 err = config_read_complex_options(config);
1622 if (_Py_INIT_FAILED(err)) {
1623 return err;
1624 }
1625
Victor Stinner6c785c02018-08-01 17:56:14 +02001626 if (config->home == NULL) {
1627 err = config_init_home(config);
1628 if (_Py_INIT_FAILED(err)) {
1629 return err;
1630 }
1631 }
1632
Steve Dower177a41a2018-11-17 20:41:48 -08001633 if (config->executable == NULL) {
1634 err = config_init_executable(config);
1635 if (_Py_INIT_FAILED(err)) {
1636 return err;
1637 }
1638 }
1639
Victor Stinner6c785c02018-08-01 17:56:14 +02001640 if (config->_install_importlib) {
1641 err = _PyCoreConfig_InitPathConfig(config);
1642 if (_Py_INIT_FAILED(err)) {
1643 return err;
1644 }
1645 }
1646
1647 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001648 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001649 if (config->faulthandler < 0) {
1650 config->faulthandler = 1;
1651 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001652 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001653 if (config->faulthandler < 0) {
1654 config->faulthandler = 0;
1655 }
1656 if (config->tracemalloc < 0) {
1657 config->tracemalloc = 0;
1658 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001659 if (config->use_hash_seed < 0) {
1660 config->use_hash_seed = 0;
1661 config->hash_seed = 0;
1662 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001663
Victor Stinner70fead22018-08-29 13:45:34 +02001664 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner20004952019-03-26 02:31:11 +01001665 err = config_init_fs_encoding(config, preconfig);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001666 if (_Py_INIT_FAILED(err)) {
1667 return err;
1668 }
1669 }
1670
Victor Stinner20004952019-03-26 02:31:11 +01001671 err = config_init_stdio_encoding(config, preconfig);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001672 if (_Py_INIT_FAILED(err)) {
1673 return err;
1674 }
1675
Victor Stinner62599762019-03-15 16:03:23 +01001676 if (config->argv.length < 1) {
1677 /* Ensure at least one (empty) argument is seen */
1678 if (_PyWstrList_Append(&config->argv, L"") < 0) {
1679 return _Py_INIT_NO_MEMORY();
1680 }
1681 }
Victor Stinner870b0352019-05-17 03:15:12 +02001682
1683 if (config->check_hash_pycs_mode == NULL) {
1684 err = _PyCoreConfig_SetString(&config->check_hash_pycs_mode,
1685 L"default");
1686 if (_Py_INIT_FAILED(err)) {
1687 return err;
1688 }
1689 }
1690
1691 if (config->configure_c_stdio < 0) {
1692 config->configure_c_stdio = 1;
1693 }
1694
Victor Stinner6c785c02018-08-01 17:56:14 +02001695 return _Py_INIT_OK();
1696}
Victor Stinner5ed69952018-11-06 15:59:52 +01001697
1698
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001699static void
1700config_init_stdio(const _PyCoreConfig *config)
1701{
1702#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1703 /* don't translate newlines (\r\n <=> \n) */
1704 _setmode(fileno(stdin), O_BINARY);
1705 _setmode(fileno(stdout), O_BINARY);
1706 _setmode(fileno(stderr), O_BINARY);
1707#endif
1708
1709 if (!config->buffered_stdio) {
1710#ifdef HAVE_SETVBUF
1711 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1712 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1713 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1714#else /* !HAVE_SETVBUF */
1715 setbuf(stdin, (char *)NULL);
1716 setbuf(stdout, (char *)NULL);
1717 setbuf(stderr, (char *)NULL);
1718#endif /* !HAVE_SETVBUF */
1719 }
1720 else if (config->interactive) {
1721#ifdef MS_WINDOWS
1722 /* Doesn't have to have line-buffered -- use unbuffered */
1723 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1724 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1725#else /* !MS_WINDOWS */
1726#ifdef HAVE_SETVBUF
1727 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1728 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1729#endif /* HAVE_SETVBUF */
1730#endif /* !MS_WINDOWS */
1731 /* Leave stderr alone - it should be unbuffered anyway. */
1732 }
1733}
1734
1735
1736/* Write the configuration:
1737
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001738 - set Py_xxx global configuration variables
1739 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001740void
Victor Stinner43125222019-04-24 18:23:53 +02001741_PyCoreConfig_Write(const _PyCoreConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001742{
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001743 _PyCoreConfig_SetGlobalConfig(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001744
1745 if (config->configure_c_stdio) {
1746 config_init_stdio(config);
1747 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001748
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001749 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner43125222019-04-24 18:23:53 +02001750 _PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001751 preconfig->isolated = config->isolated;
1752 preconfig->use_environment = config->use_environment;
1753 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001754}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001755
1756
Victor Stinner2f549082019-03-29 15:13:46 +01001757/* --- _PyCoreConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001758
1759static void
Victor Stinner2f549082019-03-29 15:13:46 +01001760config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001761{
Victor Stinner2f549082019-03-29 15:13:46 +01001762 FILE *f = error ? stderr : stdout;
1763
1764 fprintf(f, usage_line, program);
1765 if (error)
1766 fprintf(f, "Try `python -h' for more information.\n");
1767 else {
1768 fputs(usage_1, f);
1769 fputs(usage_2, f);
1770 fputs(usage_3, f);
1771 fprintf(f, usage_4, (wint_t)DELIM);
1772 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1773 fputs(usage_6, f);
1774 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001775}
1776
1777
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001778/* Parse the command line arguments */
1779static _PyInitError
Victor Stinner870b0352019-05-17 03:15:12 +02001780config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001781 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001782{
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001783 _PyInitError err;
Victor Stinner870b0352019-05-17 03:15:12 +02001784 const _PyWstrList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001785 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001786 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001787
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001788 _PyOS_ResetGetOpt();
1789 do {
1790 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001791 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001792 if (c == EOF) {
1793 break;
1794 }
1795
1796 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001797 if (config->run_command == NULL) {
1798 /* -c is the last option; following arguments
1799 that look like options are left for the
1800 command to interpret. */
1801 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1802 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1803 if (command == NULL) {
1804 return _Py_INIT_NO_MEMORY();
1805 }
1806 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1807 command[len - 2] = '\n';
1808 command[len - 1] = 0;
1809 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001810 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001811 break;
1812 }
1813
1814 if (c == 'm') {
1815 /* -m is the last option; following arguments
1816 that look like options are left for the
1817 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001818 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001819 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1820 if (config->run_module == NULL) {
1821 return _Py_INIT_NO_MEMORY();
1822 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001823 }
1824 break;
1825 }
1826
1827 switch (c) {
1828 case 0:
1829 // Handle long option.
1830 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001831 if (wcscmp(_PyOS_optarg, L"always") == 0
1832 || wcscmp(_PyOS_optarg, L"never") == 0
1833 || wcscmp(_PyOS_optarg, L"default") == 0)
1834 {
Victor Stinner709d23d2019-05-02 14:56:30 -04001835 err = _PyCoreConfig_SetString(&config->check_hash_pycs_mode,
1836 _PyOS_optarg);
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001837 if (_Py_INIT_FAILED(err)) {
1838 return err;
1839 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001840 } else {
1841 fprintf(stderr, "--check-hash-based-pycs must be one of "
1842 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001843 config_usage(1, program);
Victor Stinner2f549082019-03-29 15:13:46 +01001844 return _Py_INIT_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001845 }
1846 break;
1847
1848 case 'b':
1849 config->bytes_warning++;
1850 break;
1851
1852 case 'd':
1853 config->parser_debug++;
1854 break;
1855
1856 case 'i':
1857 config->inspect++;
1858 config->interactive++;
1859 break;
1860
Victor Stinner6dcb5422019-03-05 02:44:12 +01001861 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001862 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001863 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001864 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001865 break;
1866
1867 /* case 'J': reserved for Jython */
1868
1869 case 'O':
1870 config->optimization_level++;
1871 break;
1872
1873 case 'B':
1874 config->write_bytecode = 0;
1875 break;
1876
1877 case 's':
1878 config->user_site_directory = 0;
1879 break;
1880
1881 case 'S':
1882 config->site_import = 0;
1883 break;
1884
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001885 case 't':
1886 /* ignored for backwards compatibility */
1887 break;
1888
1889 case 'u':
1890 config->buffered_stdio = 0;
1891 break;
1892
1893 case 'v':
1894 config->verbose++;
1895 break;
1896
1897 case 'x':
1898 config->skip_source_first_line = 1;
1899 break;
1900
1901 case 'h':
1902 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001903 config_usage(0, program);
Victor Stinner2f549082019-03-29 15:13:46 +01001904 return _Py_INIT_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001905
1906 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01001907 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001908 break;
1909
1910 case 'W':
Victor Stinner2f549082019-03-29 15:13:46 +01001911 if (_PyWstrList_Append(warnoptions, _PyOS_optarg) < 0) {
Victor Stinner74f65682019-03-15 15:08:05 +01001912 return _Py_INIT_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001913 }
1914 break;
1915
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001916 case 'q':
1917 config->quiet++;
1918 break;
1919
1920 case 'R':
1921 config->use_hash_seed = 0;
1922 break;
1923
1924 /* This space reserved for other options */
1925
1926 default:
1927 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02001928 config_usage(1, program);
Victor Stinner2f549082019-03-29 15:13:46 +01001929 return _Py_INIT_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001930 }
1931 } while (1);
1932
Victor Stinner2f549082019-03-29 15:13:46 +01001933 if (print_version) {
1934 printf("Python %s\n",
1935 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
1936 return _Py_INIT_EXIT(0);
1937 }
1938
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001939 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01001940 && _PyOS_optind < argv->length
1941 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01001942 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001943 {
Victor Stinnerfa153762019-03-20 04:25:38 +01001944 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001945 if (config->run_filename == NULL) {
1946 return _Py_INIT_NO_MEMORY();
1947 }
1948 }
1949
1950 if (config->run_command != NULL || config->run_module != NULL) {
1951 /* Backup _PyOS_optind */
1952 _PyOS_optind--;
1953 }
1954
Victor Stinnerae239f62019-05-16 17:02:56 +02001955 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001956
1957 return _Py_INIT_OK();
1958}
1959
1960
1961#ifdef MS_WINDOWS
1962# define WCSTOK wcstok_s
1963#else
1964# define WCSTOK wcstok
1965#endif
1966
1967/* Get warning options from PYTHONWARNINGS environment variable. */
1968static _PyInitError
Victor Stinner2f549082019-03-29 15:13:46 +01001969config_init_env_warnoptions(const _PyCoreConfig *config, _PyWstrList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001970{
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001971 _PyInitError err;
1972 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
1973 wchar_t *env = NULL;
1974 err = CONFIG_GET_ENV_DUP(config, &env,
1975 L"PYTHONWARNINGS", "PYTHONWARNINGS");
1976 if (_Py_INIT_FAILED(err)) {
1977 return err;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001978 }
1979
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001980 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001981 if (env == NULL) {
1982 return _Py_INIT_OK();
1983 }
1984
1985
1986 wchar_t *warning, *context = NULL;
1987 for (warning = WCSTOK(env, L",", &context);
1988 warning != NULL;
1989 warning = WCSTOK(NULL, L",", &context))
1990 {
Victor Stinner2f549082019-03-29 15:13:46 +01001991 if (_PyWstrList_Append(warnoptions, warning) < 0) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001992 PyMem_RawFree(env);
Victor Stinner74f65682019-03-15 15:08:05 +01001993 return _Py_INIT_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001994 }
1995 }
1996 PyMem_RawFree(env);
1997 return _Py_INIT_OK();
1998}
1999
2000
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002001static int
2002config_add_warnoption(_PyCoreConfig *config, const wchar_t *option)
2003{
2004 if (_PyWstrList_Find(&config->warnoptions, option)) {
2005 /* Already present: do nothing */
2006 return 0;
2007 }
2008 if (_PyWstrList_Append(&config->warnoptions, option)) {
2009 return -1;
2010 }
2011 return 0;
2012}
2013
2014
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002015static _PyInitError
Victor Stinner2f549082019-03-29 15:13:46 +01002016config_init_warnoptions(_PyCoreConfig *config,
2017 const _PyWstrList *cmdline_warnoptions,
2018 const _PyWstrList *env_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002019{
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002020 /* The priority order for warnings configuration is (highest precedence
2021 * first):
2022 *
2023 * - the BytesWarning filter, if needed ('-b', '-bb')
2024 * - any '-W' command line options; then
2025 * - the 'PYTHONWARNINGS' environment variable; then
2026 * - the dev mode filter ('-X dev', 'PYTHONDEVMODE'); then
2027 * - any implicit filters added by _warnings.c/warnings.py
2028 *
2029 * All settings except the last are passed to the warnings module via
2030 * the `sys.warnoptions` list. Since the warnings module works on the basis
2031 * of "the most recently added filter will be checked first", we add
2032 * the lowest precedence entries first so that later entries override them.
2033 */
2034
Victor Stinner20004952019-03-26 02:31:11 +01002035 if (config->dev_mode) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002036 if (config_add_warnoption(config, L"default") < 0) {
Victor Stinner74f65682019-03-15 15:08:05 +01002037 return _Py_INIT_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002038 }
2039 }
2040
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002041 Py_ssize_t i;
2042 const _PyWstrList *options;
2043
Victor Stinner2f549082019-03-29 15:13:46 +01002044 options = env_warnoptions;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002045 for (i = 0; i < options->length; i++) {
2046 if (config_add_warnoption(config, options->items[i]) < 0) {
2047 return _Py_INIT_NO_MEMORY();
2048 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002049 }
2050
Victor Stinner2f549082019-03-29 15:13:46 +01002051 options = cmdline_warnoptions;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002052 for (i = 0; i < options->length; i++) {
2053 if (config_add_warnoption(config, options->items[i]) < 0) {
2054 return _Py_INIT_NO_MEMORY();
2055 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002056 }
2057
2058 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2059 * don't even try to emit a warning, so we skip setting the filter in that
2060 * case.
2061 */
2062 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002063 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002064 if (config->bytes_warning> 1) {
2065 filter = L"error::BytesWarning";
2066 }
2067 else {
2068 filter = L"default::BytesWarning";
2069 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002070 if (config_add_warnoption(config, filter) < 0) {
Victor Stinner74f65682019-03-15 15:08:05 +01002071 return _Py_INIT_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002072 }
2073 }
2074 return _Py_INIT_OK();
2075}
2076
2077
2078static _PyInitError
Victor Stinnerb5947842019-05-18 00:38:16 +02002079config_update_argv(_PyCoreConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002080{
Victor Stinner870b0352019-05-17 03:15:12 +02002081 const _PyWstrList *cmdline_argv = &config->argv;
Victor Stinnerfa153762019-03-20 04:25:38 +01002082 _PyWstrList config_argv = _PyWstrList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002083
Victor Stinner74f65682019-03-15 15:08:05 +01002084 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002085 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002086 /* Ensure at least one (empty) argument is seen */
Victor Stinnerfa153762019-03-20 04:25:38 +01002087 if (_PyWstrList_Append(&config_argv, L"") < 0) {
Victor Stinner74f65682019-03-15 15:08:05 +01002088 return _Py_INIT_NO_MEMORY();
2089 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002090 }
2091 else {
Victor Stinner74f65682019-03-15 15:08:05 +01002092 _PyWstrList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002093 slice.length = cmdline_argv->length - opt_index;
2094 slice.items = &cmdline_argv->items[opt_index];
Victor Stinnerfa153762019-03-20 04:25:38 +01002095 if (_PyWstrList_Copy(&config_argv, &slice) < 0) {
Victor Stinner74f65682019-03-15 15:08:05 +01002096 return _Py_INIT_NO_MEMORY();
2097 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002098 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002099 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002100
2101 wchar_t *arg0 = NULL;
2102 if (config->run_command != NULL) {
2103 /* Force sys.argv[0] = '-c' */
2104 arg0 = L"-c";
2105 }
2106 else if (config->run_module != NULL) {
2107 /* Force sys.argv[0] = '-m'*/
2108 arg0 = L"-m";
2109 }
2110 if (arg0 != NULL) {
2111 arg0 = _PyMem_RawWcsdup(arg0);
2112 if (arg0 == NULL) {
Victor Stinnerfa153762019-03-20 04:25:38 +01002113 _PyWstrList_Clear(&config_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002114 return _Py_INIT_NO_MEMORY();
2115 }
2116
Victor Stinnerfa153762019-03-20 04:25:38 +01002117 PyMem_RawFree(config_argv.items[0]);
2118 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002119 }
2120
Victor Stinner74f65682019-03-15 15:08:05 +01002121 _PyWstrList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002122 config->argv = config_argv;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002123 return _Py_INIT_OK();
2124}
2125
2126
Victor Stinner5ac27a52019-03-27 13:40:14 +01002127static _PyInitError
Victor Stinner5f38b842019-05-01 02:30:12 +02002128core_read_precmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002129{
2130 _PyInitError err;
2131
Victor Stinnercab5d072019-05-17 19:01:14 +02002132 if (config->parse_argv) {
2133 if (_PyWstrList_Copy(&precmdline->argv, &config->argv) < 0) {
2134 return _Py_INIT_NO_MEMORY();
2135 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002136 }
2137
Victor Stinnercab5d072019-05-17 19:01:14 +02002138 _PyPreConfig preconfig;
2139 _PyPreConfig_Init(&preconfig);
Victor Stinnerb5947842019-05-18 00:38:16 +02002140 _PyPreConfig_Copy(&preconfig, &_PyRuntime.preconfig);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002141
Victor Stinnercab5d072019-05-17 19:01:14 +02002142 _PyPreConfig_GetCoreConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002143
2144 err = _PyPreCmdline_Read(precmdline, &preconfig);
Victor Stinner870b0352019-05-17 03:15:12 +02002145 if (_Py_INIT_FAILED(err)) {
Victor Stinnerb16b4e42019-05-17 15:20:52 +02002146 return err;
Victor Stinner870b0352019-05-17 03:15:12 +02002147 }
2148
2149 if (_PyPreCmdline_SetCoreConfig(precmdline, config) < 0) {
2150 err = _Py_INIT_NO_MEMORY();
Victor Stinnerb16b4e42019-05-17 15:20:52 +02002151 return err;
Victor Stinner870b0352019-05-17 03:15:12 +02002152 }
2153
Victor Stinnerb16b4e42019-05-17 15:20:52 +02002154 return _Py_INIT_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002155}
2156
2157
Victor Stinner2f549082019-03-29 15:13:46 +01002158static _PyInitError
Victor Stinner870b0352019-05-17 03:15:12 +02002159config_read_cmdline(_PyCoreConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002160{
2161 _PyInitError err;
2162 _PyWstrList cmdline_warnoptions = _PyWstrList_INIT;
2163 _PyWstrList env_warnoptions = _PyWstrList_INIT;
2164
Victor Stinnerae239f62019-05-16 17:02:56 +02002165 if (config->parse_argv < 0) {
2166 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002167 }
Victor Stinner870b0352019-05-17 03:15:12 +02002168
Victor Stinnerfed02e12019-05-17 11:12:09 +02002169 if (config->program_name == NULL) {
2170 err = config_init_program_name(config);
Victor Stinner870b0352019-05-17 03:15:12 +02002171 if (_Py_INIT_FAILED(err)) {
Victor Stinnerfed02e12019-05-17 11:12:09 +02002172 return err;
Victor Stinner870b0352019-05-17 03:15:12 +02002173 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002174 }
Victor Stinner2f549082019-03-29 15:13:46 +01002175
Victor Stinnerae239f62019-05-16 17:02:56 +02002176 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002177 Py_ssize_t opt_index;
Victor Stinner870b0352019-05-17 03:15:12 +02002178 err = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
Victor Stinnerae239f62019-05-16 17:02:56 +02002179 if (_Py_INIT_FAILED(err)) {
2180 goto done;
2181 }
2182
Victor Stinner870b0352019-05-17 03:15:12 +02002183 err = config_update_argv(config, opt_index);
Victor Stinnerae239f62019-05-16 17:02:56 +02002184 if (_Py_INIT_FAILED(err)) {
2185 goto done;
2186 }
Victor Stinner2f549082019-03-29 15:13:46 +01002187 }
2188
Victor Stinner2f549082019-03-29 15:13:46 +01002189 if (config->use_environment) {
2190 err = config_init_env_warnoptions(config, &env_warnoptions);
2191 if (_Py_INIT_FAILED(err)) {
2192 goto done;
2193 }
2194 }
2195
2196 err = config_init_warnoptions(config,
2197 &cmdline_warnoptions, &env_warnoptions);
2198 if (_Py_INIT_FAILED(err)) {
2199 goto done;
2200 }
2201
2202 err = _Py_INIT_OK();
2203
2204done:
2205 _PyWstrList_Clear(&cmdline_warnoptions);
2206 _PyWstrList_Clear(&env_warnoptions);
2207 return err;
2208}
2209
2210
Victor Stinner5f38b842019-05-01 02:30:12 +02002211_PyInitError
2212_PyCoreConfig_SetPyArgv(_PyCoreConfig *config, const _PyArgv *args)
2213{
Victor Stinner70005ac2019-05-02 15:25:34 -04002214 if (args->use_bytes_argv) {
2215 _PyInitError err;
2216
2217 err = _PyRuntime_Initialize();
2218 if (_Py_INIT_FAILED(err)) {
2219 return err;
2220 }
2221 _PyRuntimeState *runtime = &_PyRuntime;
2222
2223 /* do nothing if Python is already pre-initialized:
2224 _PyCoreConfig_Write() will update _PyRuntime.preconfig later */
2225 if (!runtime->pre_initialized) {
2226 err = _Py_PreInitializeFromCoreConfig(config, args);
2227 if (_Py_INIT_FAILED(err)) {
2228 return err;
2229 }
2230 }
2231 }
Victor Stinner5f38b842019-05-01 02:30:12 +02002232 return _PyArgv_AsWstrList(args, &config->argv);
2233}
2234
2235
Victor Stinner70005ac2019-05-02 15:25:34 -04002236/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2237 if needed to ensure that encodings are properly configured. */
Victor Stinner5f38b842019-05-01 02:30:12 +02002238_PyInitError
Victor Stinnerb5947842019-05-18 00:38:16 +02002239_PyCoreConfig_SetArgv(_PyCoreConfig *config, Py_ssize_t argc, char **argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002240{
2241 _PyArgv args = {
2242 .argc = argc,
2243 .use_bytes_argv = 1,
2244 .bytes_argv = argv,
2245 .wchar_argv = NULL};
2246 return _PyCoreConfig_SetPyArgv(config, &args);
2247}
2248
2249
2250_PyInitError
Victor Stinnerb5947842019-05-18 00:38:16 +02002251_PyCoreConfig_SetWideArgv(_PyCoreConfig *config, Py_ssize_t argc, wchar_t **argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002252{
2253 _PyArgv args = {
2254 .argc = argc,
2255 .use_bytes_argv = 0,
2256 .bytes_argv = NULL,
2257 .wchar_argv = argv};
2258 return _PyCoreConfig_SetPyArgv(config, &args);
2259}
2260
2261
Victor Stinner4fffd382019-03-06 01:44:31 +01002262/* Read the configuration into _PyCoreConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002263
2264 * Command line arguments
2265 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002266 * Py_xxx global configuration variables
2267
2268 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002269_PyInitError
Victor Stinner5f38b842019-05-01 02:30:12 +02002270_PyCoreConfig_Read(_PyCoreConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002271{
2272 _PyInitError err;
Victor Stinnercab5d072019-05-17 19:01:14 +02002273 _PyWstrList orig_argv = _PyWstrList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002274
Victor Stinner70005ac2019-05-02 15:25:34 -04002275 err = _Py_PreInitializeFromCoreConfig(config, NULL);
Victor Stinner6d5ee972019-03-23 12:05:43 +01002276 if (_Py_INIT_FAILED(err)) {
2277 return err;
2278 }
2279
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002280 _PyCoreConfig_GetGlobalConfig(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002281
Victor Stinnercab5d072019-05-17 19:01:14 +02002282 if (_PyWstrList_Copy(&orig_argv, &config->argv) < 0) {
2283 return _Py_INIT_NO_MEMORY();
2284 }
2285
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002286 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner5f38b842019-05-01 02:30:12 +02002287 err = core_read_precmdline(config, &precmdline);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002288 if (_Py_INIT_FAILED(err)) {
2289 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002290 }
2291
Victor Stinner870b0352019-05-17 03:15:12 +02002292 assert(config->isolated >= 0);
2293 if (config->isolated) {
2294 config->use_environment = 0;
2295 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002296 }
2297
Victor Stinner870b0352019-05-17 03:15:12 +02002298 err = config_read_cmdline(config);
2299 if (_Py_INIT_FAILED(err)) {
2300 goto done;
2301 }
2302
2303 err = config_read(config);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002304 if (_Py_INIT_FAILED(err)) {
2305 goto done;
2306 }
2307
Victor Stinnercab5d072019-05-17 19:01:14 +02002308 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002309 err = _Py_INIT_NO_MEMORY();
2310 goto done;
2311 }
2312
2313 /* Check config consistency */
2314 assert(config->isolated >= 0);
2315 assert(config->use_environment >= 0);
2316 assert(config->dev_mode >= 0);
2317 assert(config->install_signal_handlers >= 0);
2318 assert(config->use_hash_seed >= 0);
2319 assert(config->faulthandler >= 0);
2320 assert(config->tracemalloc >= 0);
2321 assert(config->site_import >= 0);
2322 assert(config->bytes_warning >= 0);
2323 assert(config->inspect >= 0);
2324 assert(config->interactive >= 0);
2325 assert(config->optimization_level >= 0);
2326 assert(config->parser_debug >= 0);
2327 assert(config->write_bytecode >= 0);
2328 assert(config->verbose >= 0);
2329 assert(config->quiet >= 0);
2330 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002331 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002332 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002333 assert(config->buffered_stdio >= 0);
2334 assert(config->program_name != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002335 assert(_PyWstrList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002336 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2337 assert(config->argv.length >= 1);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002338 assert(_PyWstrList_CheckConsistency(&config->xoptions));
2339 assert(_PyWstrList_CheckConsistency(&config->warnoptions));
2340 assert(_PyWstrList_CheckConsistency(&config->module_search_paths));
2341 if (config->_install_importlib) {
Victor Stinner54b43bb2019-05-16 18:30:15 +02002342 assert(config->use_module_search_paths != 0);
2343 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002344 assert(config->executable != NULL);
2345 assert(config->prefix != NULL);
2346 assert(config->base_prefix != NULL);
2347 assert(config->exec_prefix != NULL);
2348 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002349 }
2350 assert(config->filesystem_encoding != NULL);
2351 assert(config->filesystem_errors != NULL);
2352 assert(config->stdio_encoding != NULL);
2353 assert(config->stdio_errors != NULL);
2354#ifdef MS_WINDOWS
2355 assert(config->legacy_windows_stdio >= 0);
2356#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002357 /* -c and -m options are exclusive */
2358 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002359 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002360 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002361 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002362
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002363 err = _Py_INIT_OK();
2364
2365done:
Victor Stinnercab5d072019-05-17 19:01:14 +02002366 _PyWstrList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002367 _PyPreCmdline_Clear(&precmdline);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002368 return err;
2369}
Victor Stinner1075d162019-03-25 23:19:57 +01002370
2371
2372PyObject*
2373_Py_GetConfigsAsDict(void)
2374{
2375 PyObject *config = NULL;
2376 PyObject *dict = NULL;
2377
2378 config = PyDict_New();
2379 if (config == NULL) {
2380 goto error;
2381 }
2382
2383 /* global config */
2384 dict = _Py_GetGlobalVariablesAsDict();
2385 if (dict == NULL) {
2386 goto error;
2387 }
2388 if (PyDict_SetItemString(config, "global_config", dict) < 0) {
2389 goto error;
2390 }
2391 Py_CLEAR(dict);
2392
2393 /* pre config */
2394 PyInterpreterState *interp = _PyInterpreterState_Get();
Victor Stinner20004952019-03-26 02:31:11 +01002395 const _PyPreConfig *pre_config = &_PyRuntime.preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002396 dict = _PyPreConfig_AsDict(pre_config);
2397 if (dict == NULL) {
2398 goto error;
2399 }
2400 if (PyDict_SetItemString(config, "pre_config", dict) < 0) {
2401 goto error;
2402 }
2403 Py_CLEAR(dict);
2404
2405 /* core config */
Victor Stinner20004952019-03-26 02:31:11 +01002406 const _PyCoreConfig *core_config = _PyInterpreterState_GetCoreConfig(interp);
Victor Stinner1075d162019-03-25 23:19:57 +01002407 dict = _PyCoreConfig_AsDict(core_config);
2408 if (dict == NULL) {
2409 goto error;
2410 }
2411 if (PyDict_SetItemString(config, "core_config", dict) < 0) {
2412 goto error;
2413 }
2414 Py_CLEAR(dict);
2415
Victor Stinner1075d162019-03-25 23:19:57 +01002416 return config;
2417
2418error:
2419 Py_XDECREF(config);
2420 Py_XDECREF(dict);
2421 return NULL;
2422}