blob: 958845e488d7f23f157714b94a7eb200d09b77cb [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;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200554 config->_config_init = (int)_PyCoreConfig_INIT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200555 config->isolated = -1;
556 config->use_environment = -1;
557 config->dev_mode = -1;
558 config->install_signal_handlers = 1;
559 config->use_hash_seed = -1;
560 config->faulthandler = -1;
561 config->tracemalloc = -1;
562 config->use_module_search_paths = 0;
563 config->parse_argv = 0;
564 config->site_import = -1;
565 config->bytes_warning = -1;
566 config->inspect = -1;
567 config->interactive = -1;
568 config->optimization_level = -1;
569 config->parser_debug= -1;
570 config->write_bytecode = -1;
571 config->verbose = -1;
572 config->quiet = -1;
573 config->user_site_directory = -1;
574 config->configure_c_stdio = 0;
575 config->buffered_stdio = -1;
576 config->_install_importlib = 1;
577 config->check_hash_pycs_mode = NULL;
578 config->pathconfig_warnings = -1;
579 config->_init_main = 1;
580#ifdef MS_WINDOWS
581 config->legacy_windows_stdio = -1;
582#endif
583}
584
585
586static void
587_PyCoreConfig_InitDefaults(_PyCoreConfig *config)
588{
589 _PyCoreConfig_Init(config);
590
591 config->isolated = 0;
592 config->use_environment = 1;
593 config->site_import = 1;
594 config->bytes_warning = 0;
595 config->inspect = 0;
596 config->interactive = 0;
597 config->optimization_level = 0;
598 config->parser_debug= 0;
599 config->write_bytecode = 1;
600 config->verbose = 0;
601 config->quiet = 0;
602 config->user_site_directory = 1;
603 config->buffered_stdio = 1;
604 config->pathconfig_warnings = 1;
605#ifdef MS_WINDOWS
606 config->legacy_windows_stdio = 0;
607#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200608}
609
610
611_PyInitError
612_PyCoreConfig_InitPythonConfig(_PyCoreConfig *config)
613{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200614 _PyCoreConfig_InitDefaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200615
Victor Stinner6d1c4672019-05-20 11:02:00 +0200616 config->_config_init = (int)_PyCoreConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200617 config->configure_c_stdio = 1;
618 config->parse_argv = 1;
619
620 return _Py_INIT_OK();
621}
622
623
624_PyInitError
625_PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config)
626{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200627 _PyCoreConfig_InitDefaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200628
Victor Stinner6d1c4672019-05-20 11:02:00 +0200629 config->_config_init = (int)_PyCoreConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200630 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200631 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200632 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200633 config->dev_mode = 0;
634 config->install_signal_handlers = 0;
635 config->use_hash_seed = 0;
636 config->faulthandler = 0;
637 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200638 config->pathconfig_warnings = 0;
639#ifdef MS_WINDOWS
640 config->legacy_windows_stdio = 0;
641#endif
642
643 return _Py_INIT_OK();
644}
645
646
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200647/* Copy str into *config_str (duplicate the string) */
648_PyInitError
Victor Stinner6d1c4672019-05-20 11:02:00 +0200649_PyCoreConfig_SetString(_PyCoreConfig *config, wchar_t **config_str,
650 const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200651{
Victor Stinner6d1c4672019-05-20 11:02:00 +0200652 _PyInitError err = _Py_PreInitializeFromCoreConfig(config, NULL);
653 if (_Py_INIT_FAILED(err)) {
654 return err;
655 }
656
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200657 wchar_t *str2;
658 if (str != NULL) {
659 str2 = _PyMem_RawWcsdup(str);
660 if (str2 == NULL) {
661 return _Py_INIT_NO_MEMORY();
662 }
663 }
664 else {
665 str2 = NULL;
666 }
667 PyMem_RawFree(*config_str);
668 *config_str = str2;
669 return _Py_INIT_OK();
670}
671
672
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200673static _PyInitError
Victor Stinner6d1c4672019-05-20 11:02:00 +0200674_PyCoreConfig_DecodeLocaleErr(_PyCoreConfig *config, wchar_t **config_str,
675 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200676{
Victor Stinner6d1c4672019-05-20 11:02:00 +0200677 _PyInitError err = _Py_PreInitializeFromCoreConfig(config, NULL);
Victor Stinner70005ac2019-05-02 15:25:34 -0400678 if (_Py_INIT_FAILED(err)) {
679 return err;
680 }
681
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200682 wchar_t *str2;
683 if (str != NULL) {
684 size_t len;
685 str2 = Py_DecodeLocale(str, &len);
686 if (str2 == NULL) {
687 if (len == (size_t)-2) {
688 return _Py_INIT_ERR(decode_err_msg);
689 }
690 else {
691 return _Py_INIT_NO_MEMORY();
692 }
693 }
694 }
695 else {
696 str2 = NULL;
697 }
698 PyMem_RawFree(*config_str);
699 *config_str = str2;
700 return _Py_INIT_OK();
701}
702
703
Victor Stinner6d1c4672019-05-20 11:02:00 +0200704#define CONFIG_DECODE_LOCALE(config, config_str, str, NAME) \
705 _PyCoreConfig_DecodeLocaleErr(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400706
707
Victor Stinner70005ac2019-05-02 15:25:34 -0400708/* Decode str using Py_DecodeLocale() and set the result into *config_str.
709 Pre-initialize Python if needed to ensure that encodings are properly
710 configured. */
Victor Stinner709d23d2019-05-02 14:56:30 -0400711_PyInitError
Victor Stinner6d1c4672019-05-20 11:02:00 +0200712_PyCoreConfig_DecodeLocale(_PyCoreConfig *config, wchar_t **config_str,
713 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400714{
Victor Stinner6d1c4672019-05-20 11:02:00 +0200715 return CONFIG_DECODE_LOCALE(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400716}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200717
718
719_PyInitError
Victor Stinner6c785c02018-08-01 17:56:14 +0200720_PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
721{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200722 _PyInitError err;
Victor Stinner6c785c02018-08-01 17:56:14 +0200723 _PyCoreConfig_Clear(config);
724
725#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200726#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200727 do { \
Victor Stinner6d1c4672019-05-20 11:02:00 +0200728 err = _PyCoreConfig_SetString(config, &config->ATTR, config2->ATTR); \
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200729 if (_Py_INIT_FAILED(err)) { \
730 return err; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200731 } \
732 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100733#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200734 do { \
Victor Stinner74f65682019-03-15 15:08:05 +0100735 if (_PyWstrList_Copy(&config->LIST, &config2->LIST) < 0 ) { \
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200736 return _Py_INIT_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200737 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200738 } while (0)
739
Victor Stinner6d1c4672019-05-20 11:02:00 +0200740 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100741 COPY_ATTR(isolated);
742 COPY_ATTR(use_environment);
743 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200744 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200745 COPY_ATTR(use_hash_seed);
746 COPY_ATTR(hash_seed);
747 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200748 COPY_ATTR(faulthandler);
749 COPY_ATTR(tracemalloc);
750 COPY_ATTR(import_time);
751 COPY_ATTR(show_ref_count);
752 COPY_ATTR(show_alloc_count);
753 COPY_ATTR(dump_refs);
754 COPY_ATTR(malloc_stats);
755
Victor Stinner124b9eb2018-08-29 01:29:06 +0200756 COPY_WSTR_ATTR(pycache_prefix);
757 COPY_WSTR_ATTR(module_search_path_env);
758 COPY_WSTR_ATTR(home);
759 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200760
Victor Stinnerae239f62019-05-16 17:02:56 +0200761 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100762 COPY_WSTRLIST(argv);
763 COPY_WSTRLIST(warnoptions);
764 COPY_WSTRLIST(xoptions);
765 COPY_WSTRLIST(module_search_paths);
766 COPY_ATTR(use_module_search_paths);
Victor Stinner6c785c02018-08-01 17:56:14 +0200767
Victor Stinner124b9eb2018-08-29 01:29:06 +0200768 COPY_WSTR_ATTR(executable);
769 COPY_WSTR_ATTR(prefix);
770 COPY_WSTR_ATTR(base_prefix);
771 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200772 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200773
Victor Stinner6c785c02018-08-01 17:56:14 +0200774 COPY_ATTR(site_import);
775 COPY_ATTR(bytes_warning);
776 COPY_ATTR(inspect);
777 COPY_ATTR(interactive);
778 COPY_ATTR(optimization_level);
779 COPY_ATTR(parser_debug);
780 COPY_ATTR(write_bytecode);
781 COPY_ATTR(verbose);
782 COPY_ATTR(quiet);
783 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200784 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200785 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400786 COPY_WSTR_ATTR(filesystem_encoding);
787 COPY_WSTR_ATTR(filesystem_errors);
788 COPY_WSTR_ATTR(stdio_encoding);
789 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200790#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200791 COPY_ATTR(legacy_windows_stdio);
792#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100793 COPY_ATTR(skip_source_first_line);
794 COPY_WSTR_ATTR(run_command);
795 COPY_WSTR_ATTR(run_module);
796 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400797 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200798 COPY_ATTR(pathconfig_warnings);
799 COPY_ATTR(_init_main);
Victor Stinner6c785c02018-08-01 17:56:14 +0200800
801#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200802#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200803#undef COPY_WSTRLIST
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200804 return _Py_INIT_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200805}
806
807
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100808static PyObject *
809_PyCoreConfig_AsDict(const _PyCoreConfig *config)
810{
811 PyObject *dict;
812
813 dict = PyDict_New();
814 if (dict == NULL) {
815 return NULL;
816 }
817
818#define SET_ITEM(KEY, EXPR) \
819 do { \
820 PyObject *obj = (EXPR); \
821 if (obj == NULL) { \
822 goto fail; \
823 } \
824 int res = PyDict_SetItemString(dict, (KEY), obj); \
825 Py_DECREF(obj); \
826 if (res < 0) { \
827 goto fail; \
828 } \
829 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100830#define SET_ITEM_INT(ATTR) \
831 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
832#define SET_ITEM_UINT(ATTR) \
833 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100834#define FROM_WSTRING(STR) \
835 ((STR != NULL) ? \
836 PyUnicode_FromWideChar(STR, -1) \
837 : (Py_INCREF(Py_None), Py_None))
838#define SET_ITEM_WSTR(ATTR) \
839 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
840#define SET_ITEM_WSTRLIST(LIST) \
841 SET_ITEM(#LIST, _PyWstrList_AsList(&config->LIST))
842
Victor Stinner6d1c4672019-05-20 11:02:00 +0200843 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100844 SET_ITEM_INT(isolated);
845 SET_ITEM_INT(use_environment);
846 SET_ITEM_INT(dev_mode);
847 SET_ITEM_INT(install_signal_handlers);
848 SET_ITEM_INT(use_hash_seed);
849 SET_ITEM_UINT(hash_seed);
850 SET_ITEM_INT(faulthandler);
851 SET_ITEM_INT(tracemalloc);
852 SET_ITEM_INT(import_time);
853 SET_ITEM_INT(show_ref_count);
854 SET_ITEM_INT(show_alloc_count);
855 SET_ITEM_INT(dump_refs);
856 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400857 SET_ITEM_WSTR(filesystem_encoding);
858 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100859 SET_ITEM_WSTR(pycache_prefix);
860 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200861 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100862 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100863 SET_ITEM_WSTRLIST(xoptions);
864 SET_ITEM_WSTRLIST(warnoptions);
865 SET_ITEM_WSTR(module_search_path_env);
866 SET_ITEM_WSTR(home);
867 SET_ITEM_WSTRLIST(module_search_paths);
868 SET_ITEM_WSTR(executable);
869 SET_ITEM_WSTR(prefix);
870 SET_ITEM_WSTR(base_prefix);
871 SET_ITEM_WSTR(exec_prefix);
872 SET_ITEM_WSTR(base_exec_prefix);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100873 SET_ITEM_INT(site_import);
874 SET_ITEM_INT(bytes_warning);
875 SET_ITEM_INT(inspect);
876 SET_ITEM_INT(interactive);
877 SET_ITEM_INT(optimization_level);
878 SET_ITEM_INT(parser_debug);
879 SET_ITEM_INT(write_bytecode);
880 SET_ITEM_INT(verbose);
881 SET_ITEM_INT(quiet);
882 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200883 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100884 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400885 SET_ITEM_WSTR(stdio_encoding);
886 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100887#ifdef MS_WINDOWS
888 SET_ITEM_INT(legacy_windows_stdio);
889#endif
890 SET_ITEM_INT(skip_source_first_line);
891 SET_ITEM_WSTR(run_command);
892 SET_ITEM_WSTR(run_module);
893 SET_ITEM_WSTR(run_filename);
894 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400895 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200896 SET_ITEM_INT(pathconfig_warnings);
897 SET_ITEM_INT(_init_main);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100898
899 return dict;
900
901fail:
902 Py_DECREF(dict);
903 return NULL;
904
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100905#undef FROM_WSTRING
906#undef SET_ITEM
907#undef SET_ITEM_INT
908#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100909#undef SET_ITEM_WSTR
910#undef SET_ITEM_WSTRLIST
911}
912
913
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100914static const char*
Victor Stinner6c785c02018-08-01 17:56:14 +0200915_PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name)
916{
Victor Stinner20004952019-03-26 02:31:11 +0100917 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200918}
919
920
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100921/* Get a copy of the environment variable as wchar_t*.
922 Return 0 on success, but *dest can be NULL.
923 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200924static _PyInitError
Victor Stinner6d1c4672019-05-20 11:02:00 +0200925_PyCoreConfig_GetEnvDup(_PyCoreConfig *config,
Victor Stinner6c785c02018-08-01 17:56:14 +0200926 wchar_t **dest,
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200927 wchar_t *wname, char *name,
928 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +0200929{
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200930 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +0100931 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +0200932
Victor Stinner20004952019-03-26 02:31:11 +0100933 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200934 *dest = NULL;
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200935 return _Py_INIT_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200936 }
937
938#ifdef MS_WINDOWS
939 const wchar_t *var = _wgetenv(wname);
940 if (!var || var[0] == '\0') {
941 *dest = NULL;
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200942 return _Py_INIT_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200943 }
944
Victor Stinner6d1c4672019-05-20 11:02:00 +0200945 return _PyCoreConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +0200946#else
947 const char *var = getenv(name);
948 if (!var || var[0] == '\0') {
949 *dest = NULL;
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200950 return _Py_INIT_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200951 }
952
Victor Stinner6d1c4672019-05-20 11:02:00 +0200953 return _PyCoreConfig_DecodeLocaleErr(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +0200954#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200955}
956
957
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200958#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
959 _PyCoreConfig_GetEnvDup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
960
961
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100962static void
Victor Stinner6c785c02018-08-01 17:56:14 +0200963_PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
964{
965#define COPY_FLAG(ATTR, VALUE) \
966 if (config->ATTR == -1) { \
967 config->ATTR = VALUE; \
968 }
969#define COPY_NOT_FLAG(ATTR, VALUE) \
970 if (config->ATTR == -1) { \
971 config->ATTR = !(VALUE); \
972 }
973
Victor Stinner20004952019-03-26 02:31:11 +0100974 COPY_FLAG(isolated, Py_IsolatedFlag);
975 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +0200976 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
977 COPY_FLAG(inspect, Py_InspectFlag);
978 COPY_FLAG(interactive, Py_InteractiveFlag);
979 COPY_FLAG(optimization_level, Py_OptimizeFlag);
980 COPY_FLAG(parser_debug, Py_DebugFlag);
981 COPY_FLAG(verbose, Py_VerboseFlag);
982 COPY_FLAG(quiet, Py_QuietFlag);
983#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200984 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
985#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200986 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +0200987
Victor Stinner6c785c02018-08-01 17:56:14 +0200988 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
989 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
990 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
991 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
992
Victor Stinner6c785c02018-08-01 17:56:14 +0200993#undef COPY_FLAG
994#undef COPY_NOT_FLAG
995}
996
997
998/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100999static void
Victor Stinner6c785c02018-08-01 17:56:14 +02001000_PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
1001{
1002#define COPY_FLAG(ATTR, VAR) \
1003 if (config->ATTR != -1) { \
1004 VAR = config->ATTR; \
1005 }
1006#define COPY_NOT_FLAG(ATTR, VAR) \
1007 if (config->ATTR != -1) { \
1008 VAR = !config->ATTR; \
1009 }
1010
Victor Stinner20004952019-03-26 02:31:11 +01001011 COPY_FLAG(isolated, Py_IsolatedFlag);
1012 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001013 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1014 COPY_FLAG(inspect, Py_InspectFlag);
1015 COPY_FLAG(interactive, Py_InteractiveFlag);
1016 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1017 COPY_FLAG(parser_debug, Py_DebugFlag);
1018 COPY_FLAG(verbose, Py_VerboseFlag);
1019 COPY_FLAG(quiet, Py_QuietFlag);
1020#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001021 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1022#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001023 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001024
Victor Stinner6c785c02018-08-01 17:56:14 +02001025 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1026 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1027 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1028 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1029
Victor Stinner6c785c02018-08-01 17:56:14 +02001030 /* Random or non-zero hash seed */
1031 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1032 config->hash_seed != 0);
1033
1034#undef COPY_FLAG
1035#undef COPY_NOT_FLAG
1036}
1037
1038
1039/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1040 environment variables on macOS if available. */
1041static _PyInitError
1042config_init_program_name(_PyCoreConfig *config)
1043{
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001044 _PyInitError err;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001045
Victor Stinner6c785c02018-08-01 17:56:14 +02001046 /* If Py_SetProgramName() was called, use its value */
1047 const wchar_t *program_name = _Py_path_config.program_name;
1048 if (program_name != NULL) {
1049 config->program_name = _PyMem_RawWcsdup(program_name);
1050 if (config->program_name == NULL) {
1051 return _Py_INIT_NO_MEMORY();
1052 }
1053 return _Py_INIT_OK();
1054 }
1055
1056#ifdef __APPLE__
1057 /* On MacOS X, when the Python interpreter is embedded in an
1058 application bundle, it gets executed by a bootstrapping script
1059 that does os.execve() with an argv[0] that's different from the
1060 actual Python executable. This is needed to keep the Finder happy,
1061 or rather, to work around Apple's overly strict requirements of
1062 the process name. However, we still need a usable sys.executable,
1063 so the actual executable path is passed in an environment variable.
1064 See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
1065 script. */
1066 const char *p = _PyCoreConfig_GetEnv(config, "PYTHONEXECUTABLE");
1067 if (p != NULL) {
Victor Stinner6d1c4672019-05-20 11:02:00 +02001068 err = CONFIG_DECODE_LOCALE(config, &config->program_name, p,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001069 "PYTHONEXECUTABLE environment variable");
1070 if (_Py_INIT_FAILED(err)) {
1071 return err;
Victor Stinner6c785c02018-08-01 17:56:14 +02001072 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001073 return _Py_INIT_OK();
1074 }
1075#ifdef WITH_NEXT_FRAMEWORK
1076 else {
1077 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1078 if (pyvenv_launcher && *pyvenv_launcher) {
1079 /* Used by Mac/Tools/pythonw.c to forward
1080 * the argv0 of the stub executable
1081 */
Victor Stinner6d1c4672019-05-20 11:02:00 +02001082 err = CONFIG_DECODE_LOCALE(config,
1083 &config->program_name, pyvenv_launcher,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001084 "__PYVENV_LAUNCHER__ environment variable");
1085 if (_Py_INIT_FAILED(err)) {
1086 return err;
Victor Stinner6c785c02018-08-01 17:56:14 +02001087 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001088 return _Py_INIT_OK();
1089 }
1090 }
1091#endif /* WITH_NEXT_FRAMEWORK */
1092#endif /* __APPLE__ */
1093
Victor Stinnerfed02e12019-05-17 11:12:09 +02001094 /* Use argv[0] if available and non-empty */
1095 const _PyWstrList *argv = &config->argv;
1096 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1097 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1098 if (config->program_name == NULL) {
1099 return _Py_INIT_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001100 }
1101 return _Py_INIT_OK();
1102 }
1103
Victor Stinnerfed02e12019-05-17 11:12:09 +02001104 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001105#ifdef MS_WINDOWS
1106 const wchar_t *default_program_name = L"python";
1107#else
1108 const wchar_t *default_program_name = L"python3";
1109#endif
Victor Stinner6d1c4672019-05-20 11:02:00 +02001110 err = _PyCoreConfig_SetString(config, &config->program_name,
1111 default_program_name);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001112 if (_Py_INIT_FAILED(err)) {
1113 return err;
Victor Stinner6c785c02018-08-01 17:56:14 +02001114 }
1115 return _Py_INIT_OK();
1116}
1117
Steve Dower177a41a2018-11-17 20:41:48 -08001118static _PyInitError
1119config_init_executable(_PyCoreConfig *config)
1120{
1121 assert(config->executable == NULL);
1122
1123 /* If Py_SetProgramFullPath() was called, use its value */
1124 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1125 if (program_full_path != NULL) {
Victor Stinner6d1c4672019-05-20 11:02:00 +02001126 _PyInitError err = _PyCoreConfig_SetString(config,
1127 &config->executable,
Victor Stinner709d23d2019-05-02 14:56:30 -04001128 program_full_path);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001129 if (_Py_INIT_FAILED(err)) {
1130 return err;
Steve Dower177a41a2018-11-17 20:41:48 -08001131 }
1132 return _Py_INIT_OK();
1133 }
Steve Dower177a41a2018-11-17 20:41:48 -08001134 return _Py_INIT_OK();
1135}
Victor Stinner6c785c02018-08-01 17:56:14 +02001136
Victor Stinner4fffd382019-03-06 01:44:31 +01001137
Victor Stinner6c785c02018-08-01 17:56:14 +02001138static const wchar_t*
1139config_get_xoption(const _PyCoreConfig *config, wchar_t *name)
1140{
Victor Stinner74f65682019-03-15 15:08:05 +01001141 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001142}
1143
1144
1145static _PyInitError
1146config_init_home(_PyCoreConfig *config)
1147{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001148 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001149
1150 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001151 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001152 if (home) {
Victor Stinner6d1c4672019-05-20 11:02:00 +02001153 _PyInitError err = _PyCoreConfig_SetString(config, &config->home, home);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001154 if (_Py_INIT_FAILED(err)) {
1155 return err;
Victor Stinner6c785c02018-08-01 17:56:14 +02001156 }
1157 return _Py_INIT_OK();
1158 }
1159
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001160 return CONFIG_GET_ENV_DUP(config, &config->home,
1161 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001162}
1163
1164
1165static _PyInitError
1166config_init_hash_seed(_PyCoreConfig *config)
1167{
1168 const char *seed_text = _PyCoreConfig_GetEnv(config, "PYTHONHASHSEED");
1169
1170 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1171 /* Convert a text seed to a numeric one */
1172 if (seed_text && strcmp(seed_text, "random") != 0) {
1173 const char *endptr = seed_text;
1174 unsigned long seed;
1175 errno = 0;
1176 seed = strtoul(seed_text, (char **)&endptr, 10);
1177 if (*endptr != '\0'
1178 || seed > 4294967295UL
1179 || (errno == ERANGE && seed == ULONG_MAX))
1180 {
Victor Stinnerdb719752019-05-01 05:35:33 +02001181 return _Py_INIT_ERR("PYTHONHASHSEED must be \"random\" "
1182 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001183 }
1184 /* Use a specific hash */
1185 config->use_hash_seed = 1;
1186 config->hash_seed = seed;
1187 }
1188 else {
1189 /* Use a random hash */
1190 config->use_hash_seed = 0;
1191 config->hash_seed = 0;
1192 }
1193 return _Py_INIT_OK();
1194}
1195
1196
Victor Stinner6c785c02018-08-01 17:56:14 +02001197static int
1198config_wstr_to_int(const wchar_t *wstr, int *result)
1199{
1200 const wchar_t *endptr = wstr;
1201 errno = 0;
1202 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1203 if (*endptr != '\0' || errno == ERANGE) {
1204 return -1;
1205 }
1206 if (value < INT_MIN || value > INT_MAX) {
1207 return -1;
1208 }
1209
1210 *result = (int)value;
1211 return 0;
1212}
1213
1214
Victor Stinner6c785c02018-08-01 17:56:14 +02001215static _PyInitError
1216config_read_env_vars(_PyCoreConfig *config)
1217{
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001218 _PyInitError err;
Victor Stinner20004952019-03-26 02:31:11 +01001219 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001220
Victor Stinner6c785c02018-08-01 17:56:14 +02001221 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001222 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1223 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1224 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1225 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001226
1227 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001228 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001229 if (dont_write_bytecode) {
1230 config->write_bytecode = 0;
1231 }
1232
1233 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001234 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001235 if (no_user_site_directory) {
1236 config->user_site_directory = 0;
1237 }
1238
1239 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001240 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001241 if (unbuffered_stdio) {
1242 config->buffered_stdio = 0;
1243 }
1244
1245#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001246 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinner6c785c02018-08-01 17:56:14 +02001247 "PYTHONLEGACYWINDOWSSTDIO");
1248#endif
1249
Victor Stinner6c785c02018-08-01 17:56:14 +02001250 if (_PyCoreConfig_GetEnv(config, "PYTHONDUMPREFS")) {
1251 config->dump_refs = 1;
1252 }
1253 if (_PyCoreConfig_GetEnv(config, "PYTHONMALLOCSTATS")) {
1254 config->malloc_stats = 1;
1255 }
1256
Victor Stinner4a1468e2019-03-20 03:11:38 +01001257 if (config->module_search_path_env == NULL) {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001258 err = CONFIG_GET_ENV_DUP(config, &config->module_search_path_env,
1259 L"PYTHONPATH", "PYTHONPATH");
1260 if (_Py_INIT_FAILED(err)) {
1261 return err;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001262 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001263 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001264
1265 if (config->use_hash_seed < 0) {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001266 err = config_init_hash_seed(config);
Victor Stinner6c785c02018-08-01 17:56:14 +02001267 if (_Py_INIT_FAILED(err)) {
1268 return err;
1269 }
1270 }
1271
1272 return _Py_INIT_OK();
1273}
1274
1275
1276static _PyInitError
1277config_init_tracemalloc(_PyCoreConfig *config)
1278{
1279 int nframe;
1280 int valid;
1281
1282 const char *env = _PyCoreConfig_GetEnv(config, "PYTHONTRACEMALLOC");
1283 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001284 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001285 valid = (nframe >= 0);
1286 }
1287 else {
1288 valid = 0;
1289 }
1290 if (!valid) {
Victor Stinnerdb719752019-05-01 05:35:33 +02001291 return _Py_INIT_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001292 }
1293 config->tracemalloc = nframe;
1294 }
1295
1296 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1297 if (xoption) {
1298 const wchar_t *sep = wcschr(xoption, L'=');
1299 if (sep) {
1300 if (!config_wstr_to_int(sep + 1, &nframe)) {
1301 valid = (nframe >= 0);
1302 }
1303 else {
1304 valid = 0;
1305 }
1306 if (!valid) {
Victor Stinnerdb719752019-05-01 05:35:33 +02001307 return _Py_INIT_ERR("-X tracemalloc=NFRAME: "
1308 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001309 }
1310 }
1311 else {
1312 /* -X tracemalloc behaves as -X tracemalloc=1 */
1313 nframe = 1;
1314 }
1315 config->tracemalloc = nframe;
1316 }
1317 return _Py_INIT_OK();
1318}
1319
1320
1321static _PyInitError
1322config_init_pycache_prefix(_PyCoreConfig *config)
1323{
1324 assert(config->pycache_prefix == NULL);
1325
1326 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1327 if (xoption) {
1328 const wchar_t *sep = wcschr(xoption, L'=');
1329 if (sep && wcslen(sep) > 1) {
1330 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1331 if (config->pycache_prefix == NULL) {
1332 return _Py_INIT_NO_MEMORY();
1333 }
1334 }
1335 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001336 // PYTHONPYCACHEPREFIX env var ignored
1337 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001338 config->pycache_prefix = NULL;
1339 }
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001340 return _Py_INIT_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001341 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001342
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001343 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1344 L"PYTHONPYCACHEPREFIX",
1345 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001346}
1347
1348
1349static _PyInitError
1350config_read_complex_options(_PyCoreConfig *config)
1351{
1352 /* More complex options configured by env var and -X option */
1353 if (config->faulthandler < 0) {
1354 if (_PyCoreConfig_GetEnv(config, "PYTHONFAULTHANDLER")
1355 || config_get_xoption(config, L"faulthandler")) {
1356 config->faulthandler = 1;
1357 }
1358 }
1359 if (_PyCoreConfig_GetEnv(config, "PYTHONPROFILEIMPORTTIME")
1360 || config_get_xoption(config, L"importtime")) {
1361 config->import_time = 1;
1362 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001363
1364 _PyInitError err;
1365 if (config->tracemalloc < 0) {
1366 err = config_init_tracemalloc(config);
1367 if (_Py_INIT_FAILED(err)) {
1368 return err;
1369 }
1370 }
1371
1372 if (config->pycache_prefix == NULL) {
1373 err = config_init_pycache_prefix(config);
1374 if (_Py_INIT_FAILED(err)) {
1375 return err;
1376 }
1377 }
1378 return _Py_INIT_OK();
1379}
1380
1381
Victor Stinner709d23d2019-05-02 14:56:30 -04001382static const wchar_t *
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001383config_get_stdio_errors(const _PyCoreConfig *config)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001384{
1385#ifndef MS_WINDOWS
1386 const char *loc = setlocale(LC_CTYPE, NULL);
1387 if (loc != NULL) {
1388 /* surrogateescape is the default in the legacy C and POSIX locales */
1389 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001390 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001391 }
1392
1393#ifdef PY_COERCE_C_LOCALE
1394 /* surrogateescape is the default in locale coercion target locales */
1395 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001396 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001397 }
1398#endif
1399 }
1400
Victor Stinner709d23d2019-05-02 14:56:30 -04001401 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001402#else
1403 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001404 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001405#endif
1406}
1407
1408
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001409static _PyInitError
Victor Stinner6d1c4672019-05-20 11:02:00 +02001410config_get_locale_encoding(_PyCoreConfig *config, wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001411{
1412#ifdef MS_WINDOWS
1413 char encoding[20];
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001414 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Victor Stinner6d1c4672019-05-20 11:02:00 +02001415 return _PyCoreConfig_DecodeLocale(config, locale_encoding, encoding);
Victor Stinnere2510952019-05-02 11:28:57 -04001416#elif defined(_Py_FORCE_UTF8_LOCALE)
Victor Stinner6d1c4672019-05-20 11:02:00 +02001417 return _PyCoreConfig_SetString(config, locale_encoding, L"utf-8");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001418#else
1419 const char *encoding = nl_langinfo(CODESET);
1420 if (!encoding || encoding[0] == '\0') {
Victor Stinnerdb719752019-05-01 05:35:33 +02001421 return _Py_INIT_ERR("failed to get the locale encoding: "
1422 "nl_langinfo(CODESET) failed");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001423 }
Victor Stinner709d23d2019-05-02 14:56:30 -04001424 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
Victor Stinner6d1c4672019-05-20 11:02:00 +02001425 return CONFIG_DECODE_LOCALE(config,
1426 locale_encoding, encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001427 "nl_langinfo(CODESET)");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001428#endif
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001429}
1430
1431
1432static _PyInitError
Victor Stinner20004952019-03-26 02:31:11 +01001433config_init_stdio_encoding(_PyCoreConfig *config,
1434 const _PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001435{
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001436 _PyInitError err;
1437
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001438 /* If Py_SetStandardStreamEncoding() have been called, use these
1439 parameters. */
1440 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner6d1c4672019-05-20 11:02:00 +02001441 err = CONFIG_DECODE_LOCALE(config, &config->stdio_encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001442 _Py_StandardStreamEncoding,
1443 "_Py_StandardStreamEncoding");
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001444 if (_Py_INIT_FAILED(err)) {
1445 return err;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001446 }
1447 }
1448
1449 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner6d1c4672019-05-20 11:02:00 +02001450 err = CONFIG_DECODE_LOCALE(config, &config->stdio_errors,
Victor Stinner709d23d2019-05-02 14:56:30 -04001451 _Py_StandardStreamErrors,
1452 "_Py_StandardStreamErrors");
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001453 if (_Py_INIT_FAILED(err)) {
1454 return err;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001455 }
1456 }
1457
1458 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
1459 return _Py_INIT_OK();
1460 }
1461
1462 /* PYTHONIOENCODING environment variable */
1463 const char *opt = _PyCoreConfig_GetEnv(config, "PYTHONIOENCODING");
1464 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001465 char *pythonioencoding = _PyMem_RawStrdup(opt);
1466 if (pythonioencoding == NULL) {
1467 return _Py_INIT_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001468 }
1469
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001470 char *errors = strchr(pythonioencoding, ':');
1471 if (errors) {
1472 *errors = '\0';
1473 errors++;
1474 if (!errors[0]) {
1475 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001476 }
1477 }
1478
1479 /* Does PYTHONIOENCODING contain an encoding? */
1480 if (pythonioencoding[0]) {
1481 if (config->stdio_encoding == NULL) {
Victor Stinner6d1c4672019-05-20 11:02:00 +02001482 err = CONFIG_DECODE_LOCALE(config, &config->stdio_encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001483 pythonioencoding,
1484 "PYTHONIOENCODING environment variable");
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001485 if (_Py_INIT_FAILED(err)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001486 PyMem_RawFree(pythonioencoding);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001487 return err;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001488 }
1489 }
1490
1491 /* If the encoding is set but not the error handler,
1492 use "strict" error handler by default.
1493 PYTHONIOENCODING=latin1 behaves as
1494 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001495 if (!errors) {
1496 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001497 }
1498 }
1499
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001500 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner6d1c4672019-05-20 11:02:00 +02001501 err = CONFIG_DECODE_LOCALE(config, &config->stdio_errors,
Victor Stinner709d23d2019-05-02 14:56:30 -04001502 errors,
1503 "PYTHONIOENCODING environment variable");
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001504 if (_Py_INIT_FAILED(err)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001505 PyMem_RawFree(pythonioencoding);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001506 return err;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001507 }
1508 }
1509
1510 PyMem_RawFree(pythonioencoding);
1511 }
1512
1513 /* UTF-8 Mode uses UTF-8/surrogateescape */
Victor Stinner20004952019-03-26 02:31:11 +01001514 if (preconfig->utf8_mode) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001515 if (config->stdio_encoding == NULL) {
Victor Stinner6d1c4672019-05-20 11:02:00 +02001516 err = _PyCoreConfig_SetString(config, &config->stdio_encoding, L"utf-8");
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001517 if (_Py_INIT_FAILED(err)) {
1518 return err;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001519 }
1520 }
1521 if (config->stdio_errors == NULL) {
Victor Stinner6d1c4672019-05-20 11:02:00 +02001522 err = _PyCoreConfig_SetString(config, &config->stdio_errors,
Victor Stinner709d23d2019-05-02 14:56:30 -04001523 L"surrogateescape");
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001524 if (_Py_INIT_FAILED(err)) {
1525 return err;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001526 }
1527 }
1528 }
1529
1530 /* Choose the default error handler based on the current locale. */
1531 if (config->stdio_encoding == NULL) {
Victor Stinner6d1c4672019-05-20 11:02:00 +02001532 err = config_get_locale_encoding(config, &config->stdio_encoding);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001533 if (_Py_INIT_FAILED(err)) {
1534 return err;
1535 }
1536 }
1537 if (config->stdio_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001538 const wchar_t *errors = config_get_stdio_errors(config);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001539 assert(errors != NULL);
1540
Victor Stinner6d1c4672019-05-20 11:02:00 +02001541 err = _PyCoreConfig_SetString(config, &config->stdio_errors, errors);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001542 if (_Py_INIT_FAILED(err)) {
1543 return err;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001544 }
1545 }
1546
1547 return _Py_INIT_OK();
1548}
1549
1550
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001551static _PyInitError
Victor Stinner20004952019-03-26 02:31:11 +01001552config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001553{
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001554 _PyInitError err;
1555
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001556 if (config->filesystem_encoding == NULL) {
Victor Stinnere2510952019-05-02 11:28:57 -04001557#ifdef _Py_FORCE_UTF8_FS_ENCODING
Victor Stinner6d1c4672019-05-20 11:02:00 +02001558 err = _PyCoreConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001559#else
Victor Stinnere2510952019-05-02 11:28:57 -04001560
1561#ifdef MS_WINDOWS
1562 if (preconfig->legacy_windows_fs_encoding) {
1563 /* Legacy Windows filesystem encoding: mbcs/replace */
Victor Stinner6d1c4672019-05-20 11:02:00 +02001564 err = _PyCoreConfig_SetString(config, &config->filesystem_encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001565 L"mbcs");
Victor Stinnere2510952019-05-02 11:28:57 -04001566 }
1567 else
1568#endif
Victor Stinner20004952019-03-26 02:31:11 +01001569 if (preconfig->utf8_mode) {
Victor Stinner6d1c4672019-05-20 11:02:00 +02001570 err = _PyCoreConfig_SetString(config, &config->filesystem_encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001571 L"utf-8");
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001572 }
Victor Stinnere2510952019-05-02 11:28:57 -04001573#ifndef MS_WINDOWS
Victor Stinner905f1ac2018-10-30 12:58:10 +01001574 else if (_Py_GetForceASCII()) {
Victor Stinner6d1c4672019-05-20 11:02:00 +02001575 err = _PyCoreConfig_SetString(config, &config->filesystem_encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001576 L"ascii");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001577 }
Victor Stinnere2510952019-05-02 11:28:57 -04001578#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001579 else {
Victor Stinnere2510952019-05-02 11:28:57 -04001580#ifdef MS_WINDOWS
1581 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
Victor Stinner6d1c4672019-05-20 11:02:00 +02001582 err = _PyCoreConfig_SetString(config, &config->filesystem_encoding,
Victor Stinner709d23d2019-05-02 14:56:30 -04001583 L"utf-8");
Victor Stinner905f1ac2018-10-30 12:58:10 +01001584#else
Victor Stinner6d1c4672019-05-20 11:02:00 +02001585 err = config_get_locale_encoding(config,
1586 &config->filesystem_encoding);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001587#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001588 }
Victor Stinnere2510952019-05-02 11:28:57 -04001589#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
Victor Stinner905f1ac2018-10-30 12:58:10 +01001590
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001591 if (_Py_INIT_FAILED(err)) {
1592 return err;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001593 }
1594 }
1595
1596 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001597 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04001598#ifdef MS_WINDOWS
1599 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001600 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04001601 }
1602 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04001603 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04001604 }
1605#else
Victor Stinner709d23d2019-05-02 14:56:30 -04001606 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04001607#endif
Victor Stinner6d1c4672019-05-20 11:02:00 +02001608 err = _PyCoreConfig_SetString(config, &config->filesystem_errors, errors);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001609 if (_Py_INIT_FAILED(err)) {
1610 return err;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001611 }
1612 }
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001613 return _Py_INIT_OK();
1614}
1615
1616
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001617static _PyInitError
Victor Stinner870b0352019-05-17 03:15:12 +02001618config_read(_PyCoreConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001619{
1620 _PyInitError err;
Victor Stinner20004952019-03-26 02:31:11 +01001621 const _PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01001622
Victor Stinner20004952019-03-26 02:31:11 +01001623 if (config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001624 err = config_read_env_vars(config);
1625 if (_Py_INIT_FAILED(err)) {
1626 return err;
1627 }
1628 }
1629
1630 /* -X options */
1631 if (config_get_xoption(config, L"showrefcount")) {
1632 config->show_ref_count = 1;
1633 }
1634 if (config_get_xoption(config, L"showalloccount")) {
1635 config->show_alloc_count = 1;
1636 }
1637
1638 err = config_read_complex_options(config);
1639 if (_Py_INIT_FAILED(err)) {
1640 return err;
1641 }
1642
Victor Stinner6c785c02018-08-01 17:56:14 +02001643 if (config->home == NULL) {
1644 err = config_init_home(config);
1645 if (_Py_INIT_FAILED(err)) {
1646 return err;
1647 }
1648 }
1649
Steve Dower177a41a2018-11-17 20:41:48 -08001650 if (config->executable == NULL) {
1651 err = config_init_executable(config);
1652 if (_Py_INIT_FAILED(err)) {
1653 return err;
1654 }
1655 }
1656
Victor Stinner6c785c02018-08-01 17:56:14 +02001657 if (config->_install_importlib) {
1658 err = _PyCoreConfig_InitPathConfig(config);
1659 if (_Py_INIT_FAILED(err)) {
1660 return err;
1661 }
1662 }
1663
1664 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01001665 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001666 if (config->faulthandler < 0) {
1667 config->faulthandler = 1;
1668 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001669 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001670 if (config->faulthandler < 0) {
1671 config->faulthandler = 0;
1672 }
1673 if (config->tracemalloc < 0) {
1674 config->tracemalloc = 0;
1675 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001676 if (config->use_hash_seed < 0) {
1677 config->use_hash_seed = 0;
1678 config->hash_seed = 0;
1679 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001680
Victor Stinner70fead22018-08-29 13:45:34 +02001681 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner20004952019-03-26 02:31:11 +01001682 err = config_init_fs_encoding(config, preconfig);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001683 if (_Py_INIT_FAILED(err)) {
1684 return err;
1685 }
1686 }
1687
Victor Stinner20004952019-03-26 02:31:11 +01001688 err = config_init_stdio_encoding(config, preconfig);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001689 if (_Py_INIT_FAILED(err)) {
1690 return err;
1691 }
1692
Victor Stinner62599762019-03-15 16:03:23 +01001693 if (config->argv.length < 1) {
1694 /* Ensure at least one (empty) argument is seen */
1695 if (_PyWstrList_Append(&config->argv, L"") < 0) {
1696 return _Py_INIT_NO_MEMORY();
1697 }
1698 }
Victor Stinner870b0352019-05-17 03:15:12 +02001699
1700 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner6d1c4672019-05-20 11:02:00 +02001701 err = _PyCoreConfig_SetString(config, &config->check_hash_pycs_mode,
Victor Stinner870b0352019-05-17 03:15:12 +02001702 L"default");
1703 if (_Py_INIT_FAILED(err)) {
1704 return err;
1705 }
1706 }
1707
1708 if (config->configure_c_stdio < 0) {
1709 config->configure_c_stdio = 1;
1710 }
1711
Victor Stinner6c785c02018-08-01 17:56:14 +02001712 return _Py_INIT_OK();
1713}
Victor Stinner5ed69952018-11-06 15:59:52 +01001714
1715
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001716static void
1717config_init_stdio(const _PyCoreConfig *config)
1718{
1719#if defined(MS_WINDOWS) || defined(__CYGWIN__)
1720 /* don't translate newlines (\r\n <=> \n) */
1721 _setmode(fileno(stdin), O_BINARY);
1722 _setmode(fileno(stdout), O_BINARY);
1723 _setmode(fileno(stderr), O_BINARY);
1724#endif
1725
1726 if (!config->buffered_stdio) {
1727#ifdef HAVE_SETVBUF
1728 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1729 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1730 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1731#else /* !HAVE_SETVBUF */
1732 setbuf(stdin, (char *)NULL);
1733 setbuf(stdout, (char *)NULL);
1734 setbuf(stderr, (char *)NULL);
1735#endif /* !HAVE_SETVBUF */
1736 }
1737 else if (config->interactive) {
1738#ifdef MS_WINDOWS
1739 /* Doesn't have to have line-buffered -- use unbuffered */
1740 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1741 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1742#else /* !MS_WINDOWS */
1743#ifdef HAVE_SETVBUF
1744 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1745 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1746#endif /* HAVE_SETVBUF */
1747#endif /* !MS_WINDOWS */
1748 /* Leave stderr alone - it should be unbuffered anyway. */
1749 }
1750}
1751
1752
1753/* Write the configuration:
1754
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001755 - set Py_xxx global configuration variables
1756 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinner20004952019-03-26 02:31:11 +01001757void
Victor Stinner43125222019-04-24 18:23:53 +02001758_PyCoreConfig_Write(const _PyCoreConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001759{
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001760 _PyCoreConfig_SetGlobalConfig(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001761
1762 if (config->configure_c_stdio) {
1763 config_init_stdio(config);
1764 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001765
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001766 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner43125222019-04-24 18:23:53 +02001767 _PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001768 preconfig->isolated = config->isolated;
1769 preconfig->use_environment = config->use_environment;
1770 preconfig->dev_mode = config->dev_mode;
Victor Stinner5ed69952018-11-06 15:59:52 +01001771}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001772
1773
Victor Stinner2f549082019-03-29 15:13:46 +01001774/* --- _PyCoreConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001775
1776static void
Victor Stinner2f549082019-03-29 15:13:46 +01001777config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001778{
Victor Stinner2f549082019-03-29 15:13:46 +01001779 FILE *f = error ? stderr : stdout;
1780
1781 fprintf(f, usage_line, program);
1782 if (error)
1783 fprintf(f, "Try `python -h' for more information.\n");
1784 else {
1785 fputs(usage_1, f);
1786 fputs(usage_2, f);
1787 fputs(usage_3, f);
1788 fprintf(f, usage_4, (wint_t)DELIM);
1789 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1790 fputs(usage_6, f);
1791 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001792}
1793
1794
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001795/* Parse the command line arguments */
1796static _PyInitError
Victor Stinner870b0352019-05-17 03:15:12 +02001797config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02001798 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001799{
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001800 _PyInitError err;
Victor Stinner870b0352019-05-17 03:15:12 +02001801 const _PyWstrList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01001802 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001803 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01001804
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001805 _PyOS_ResetGetOpt();
1806 do {
1807 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01001808 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001809 if (c == EOF) {
1810 break;
1811 }
1812
1813 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001814 if (config->run_command == NULL) {
1815 /* -c is the last option; following arguments
1816 that look like options are left for the
1817 command to interpret. */
1818 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1819 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1820 if (command == NULL) {
1821 return _Py_INIT_NO_MEMORY();
1822 }
1823 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1824 command[len - 2] = '\n';
1825 command[len - 1] = 0;
1826 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001827 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001828 break;
1829 }
1830
1831 if (c == 'm') {
1832 /* -m is the last option; following arguments
1833 that look like options are left for the
1834 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001835 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01001836 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1837 if (config->run_module == NULL) {
1838 return _Py_INIT_NO_MEMORY();
1839 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001840 }
1841 break;
1842 }
1843
1844 switch (c) {
1845 case 0:
1846 // Handle long option.
1847 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001848 if (wcscmp(_PyOS_optarg, L"always") == 0
1849 || wcscmp(_PyOS_optarg, L"never") == 0
1850 || wcscmp(_PyOS_optarg, L"default") == 0)
1851 {
Victor Stinner6d1c4672019-05-20 11:02:00 +02001852 err = _PyCoreConfig_SetString(config, &config->check_hash_pycs_mode,
Victor Stinner709d23d2019-05-02 14:56:30 -04001853 _PyOS_optarg);
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001854 if (_Py_INIT_FAILED(err)) {
1855 return err;
1856 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001857 } else {
1858 fprintf(stderr, "--check-hash-based-pycs must be one of "
1859 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02001860 config_usage(1, program);
Victor Stinner2f549082019-03-29 15:13:46 +01001861 return _Py_INIT_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001862 }
1863 break;
1864
1865 case 'b':
1866 config->bytes_warning++;
1867 break;
1868
1869 case 'd':
1870 config->parser_debug++;
1871 break;
1872
1873 case 'i':
1874 config->inspect++;
1875 config->interactive++;
1876 break;
1877
Victor Stinner6dcb5422019-03-05 02:44:12 +01001878 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001879 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01001880 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001881 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001882 break;
1883
1884 /* case 'J': reserved for Jython */
1885
1886 case 'O':
1887 config->optimization_level++;
1888 break;
1889
1890 case 'B':
1891 config->write_bytecode = 0;
1892 break;
1893
1894 case 's':
1895 config->user_site_directory = 0;
1896 break;
1897
1898 case 'S':
1899 config->site_import = 0;
1900 break;
1901
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001902 case 't':
1903 /* ignored for backwards compatibility */
1904 break;
1905
1906 case 'u':
1907 config->buffered_stdio = 0;
1908 break;
1909
1910 case 'v':
1911 config->verbose++;
1912 break;
1913
1914 case 'x':
1915 config->skip_source_first_line = 1;
1916 break;
1917
1918 case 'h':
1919 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02001920 config_usage(0, program);
Victor Stinner2f549082019-03-29 15:13:46 +01001921 return _Py_INIT_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001922
1923 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01001924 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001925 break;
1926
1927 case 'W':
Victor Stinner2f549082019-03-29 15:13:46 +01001928 if (_PyWstrList_Append(warnoptions, _PyOS_optarg) < 0) {
Victor Stinner74f65682019-03-15 15:08:05 +01001929 return _Py_INIT_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001930 }
1931 break;
1932
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001933 case 'q':
1934 config->quiet++;
1935 break;
1936
1937 case 'R':
1938 config->use_hash_seed = 0;
1939 break;
1940
1941 /* This space reserved for other options */
1942
1943 default:
1944 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02001945 config_usage(1, program);
Victor Stinner2f549082019-03-29 15:13:46 +01001946 return _Py_INIT_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001947 }
1948 } while (1);
1949
Victor Stinner2f549082019-03-29 15:13:46 +01001950 if (print_version) {
1951 printf("Python %s\n",
1952 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
1953 return _Py_INIT_EXIT(0);
1954 }
1955
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001956 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01001957 && _PyOS_optind < argv->length
1958 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01001959 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001960 {
Victor Stinnerfa153762019-03-20 04:25:38 +01001961 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001962 if (config->run_filename == NULL) {
1963 return _Py_INIT_NO_MEMORY();
1964 }
1965 }
1966
1967 if (config->run_command != NULL || config->run_module != NULL) {
1968 /* Backup _PyOS_optind */
1969 _PyOS_optind--;
1970 }
1971
Victor Stinnerae239f62019-05-16 17:02:56 +02001972 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001973
1974 return _Py_INIT_OK();
1975}
1976
1977
1978#ifdef MS_WINDOWS
1979# define WCSTOK wcstok_s
1980#else
1981# define WCSTOK wcstok
1982#endif
1983
1984/* Get warning options from PYTHONWARNINGS environment variable. */
1985static _PyInitError
Victor Stinner6d1c4672019-05-20 11:02:00 +02001986config_init_env_warnoptions(_PyCoreConfig *config, _PyWstrList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001987{
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001988 _PyInitError err;
1989 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
1990 wchar_t *env = NULL;
1991 err = CONFIG_GET_ENV_DUP(config, &env,
1992 L"PYTHONWARNINGS", "PYTHONWARNINGS");
1993 if (_Py_INIT_FAILED(err)) {
1994 return err;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001995 }
1996
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001997 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01001998 if (env == NULL) {
1999 return _Py_INIT_OK();
2000 }
2001
2002
2003 wchar_t *warning, *context = NULL;
2004 for (warning = WCSTOK(env, L",", &context);
2005 warning != NULL;
2006 warning = WCSTOK(NULL, L",", &context))
2007 {
Victor Stinner2f549082019-03-29 15:13:46 +01002008 if (_PyWstrList_Append(warnoptions, warning) < 0) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002009 PyMem_RawFree(env);
Victor Stinner74f65682019-03-15 15:08:05 +01002010 return _Py_INIT_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002011 }
2012 }
2013 PyMem_RawFree(env);
2014 return _Py_INIT_OK();
2015}
2016
2017
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002018static int
2019config_add_warnoption(_PyCoreConfig *config, const wchar_t *option)
2020{
2021 if (_PyWstrList_Find(&config->warnoptions, option)) {
2022 /* Already present: do nothing */
2023 return 0;
2024 }
2025 if (_PyWstrList_Append(&config->warnoptions, option)) {
2026 return -1;
2027 }
2028 return 0;
2029}
2030
2031
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002032static _PyInitError
Victor Stinner2f549082019-03-29 15:13:46 +01002033config_init_warnoptions(_PyCoreConfig *config,
2034 const _PyWstrList *cmdline_warnoptions,
2035 const _PyWstrList *env_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002036{
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002037 /* The priority order for warnings configuration is (highest precedence
2038 * first):
2039 *
2040 * - the BytesWarning filter, if needed ('-b', '-bb')
2041 * - any '-W' command line options; then
2042 * - the 'PYTHONWARNINGS' environment variable; then
2043 * - the dev mode filter ('-X dev', 'PYTHONDEVMODE'); then
2044 * - any implicit filters added by _warnings.c/warnings.py
2045 *
2046 * All settings except the last are passed to the warnings module via
2047 * the `sys.warnoptions` list. Since the warnings module works on the basis
2048 * of "the most recently added filter will be checked first", we add
2049 * the lowest precedence entries first so that later entries override them.
2050 */
2051
Victor Stinner20004952019-03-26 02:31:11 +01002052 if (config->dev_mode) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002053 if (config_add_warnoption(config, L"default") < 0) {
Victor Stinner74f65682019-03-15 15:08:05 +01002054 return _Py_INIT_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002055 }
2056 }
2057
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002058 Py_ssize_t i;
2059 const _PyWstrList *options;
2060
Victor Stinner2f549082019-03-29 15:13:46 +01002061 options = env_warnoptions;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002062 for (i = 0; i < options->length; i++) {
2063 if (config_add_warnoption(config, options->items[i]) < 0) {
2064 return _Py_INIT_NO_MEMORY();
2065 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002066 }
2067
Victor Stinner2f549082019-03-29 15:13:46 +01002068 options = cmdline_warnoptions;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002069 for (i = 0; i < options->length; i++) {
2070 if (config_add_warnoption(config, options->items[i]) < 0) {
2071 return _Py_INIT_NO_MEMORY();
2072 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002073 }
2074
2075 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2076 * don't even try to emit a warning, so we skip setting the filter in that
2077 * case.
2078 */
2079 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002080 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002081 if (config->bytes_warning> 1) {
2082 filter = L"error::BytesWarning";
2083 }
2084 else {
2085 filter = L"default::BytesWarning";
2086 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002087 if (config_add_warnoption(config, filter) < 0) {
Victor Stinner74f65682019-03-15 15:08:05 +01002088 return _Py_INIT_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002089 }
2090 }
2091 return _Py_INIT_OK();
2092}
2093
2094
2095static _PyInitError
Victor Stinnerb5947842019-05-18 00:38:16 +02002096config_update_argv(_PyCoreConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002097{
Victor Stinner870b0352019-05-17 03:15:12 +02002098 const _PyWstrList *cmdline_argv = &config->argv;
Victor Stinnerfa153762019-03-20 04:25:38 +01002099 _PyWstrList config_argv = _PyWstrList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002100
Victor Stinner74f65682019-03-15 15:08:05 +01002101 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002102 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002103 /* Ensure at least one (empty) argument is seen */
Victor Stinnerfa153762019-03-20 04:25:38 +01002104 if (_PyWstrList_Append(&config_argv, L"") < 0) {
Victor Stinner74f65682019-03-15 15:08:05 +01002105 return _Py_INIT_NO_MEMORY();
2106 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002107 }
2108 else {
Victor Stinner74f65682019-03-15 15:08:05 +01002109 _PyWstrList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002110 slice.length = cmdline_argv->length - opt_index;
2111 slice.items = &cmdline_argv->items[opt_index];
Victor Stinnerfa153762019-03-20 04:25:38 +01002112 if (_PyWstrList_Copy(&config_argv, &slice) < 0) {
Victor Stinner74f65682019-03-15 15:08:05 +01002113 return _Py_INIT_NO_MEMORY();
2114 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002115 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002116 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002117
2118 wchar_t *arg0 = NULL;
2119 if (config->run_command != NULL) {
2120 /* Force sys.argv[0] = '-c' */
2121 arg0 = L"-c";
2122 }
2123 else if (config->run_module != NULL) {
2124 /* Force sys.argv[0] = '-m'*/
2125 arg0 = L"-m";
2126 }
2127 if (arg0 != NULL) {
2128 arg0 = _PyMem_RawWcsdup(arg0);
2129 if (arg0 == NULL) {
Victor Stinnerfa153762019-03-20 04:25:38 +01002130 _PyWstrList_Clear(&config_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002131 return _Py_INIT_NO_MEMORY();
2132 }
2133
Victor Stinnerfa153762019-03-20 04:25:38 +01002134 PyMem_RawFree(config_argv.items[0]);
2135 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002136 }
2137
Victor Stinner74f65682019-03-15 15:08:05 +01002138 _PyWstrList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002139 config->argv = config_argv;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002140 return _Py_INIT_OK();
2141}
2142
2143
Victor Stinner5ac27a52019-03-27 13:40:14 +01002144static _PyInitError
Victor Stinner5f38b842019-05-01 02:30:12 +02002145core_read_precmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002146{
2147 _PyInitError err;
2148
Victor Stinnercab5d072019-05-17 19:01:14 +02002149 if (config->parse_argv) {
2150 if (_PyWstrList_Copy(&precmdline->argv, &config->argv) < 0) {
2151 return _Py_INIT_NO_MEMORY();
2152 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002153 }
2154
Victor Stinnercab5d072019-05-17 19:01:14 +02002155 _PyPreConfig preconfig;
Victor Stinner6d1c4672019-05-20 11:02:00 +02002156 _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002157
Victor Stinnercab5d072019-05-17 19:01:14 +02002158 _PyPreConfig_GetCoreConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002159
2160 err = _PyPreCmdline_Read(precmdline, &preconfig);
Victor Stinner870b0352019-05-17 03:15:12 +02002161 if (_Py_INIT_FAILED(err)) {
Victor Stinnerb16b4e42019-05-17 15:20:52 +02002162 return err;
Victor Stinner870b0352019-05-17 03:15:12 +02002163 }
2164
2165 if (_PyPreCmdline_SetCoreConfig(precmdline, config) < 0) {
2166 err = _Py_INIT_NO_MEMORY();
Victor Stinnerb16b4e42019-05-17 15:20:52 +02002167 return err;
Victor Stinner870b0352019-05-17 03:15:12 +02002168 }
2169
Victor Stinnerb16b4e42019-05-17 15:20:52 +02002170 return _Py_INIT_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002171}
2172
2173
Victor Stinner2f549082019-03-29 15:13:46 +01002174static _PyInitError
Victor Stinner870b0352019-05-17 03:15:12 +02002175config_read_cmdline(_PyCoreConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002176{
2177 _PyInitError err;
2178 _PyWstrList cmdline_warnoptions = _PyWstrList_INIT;
2179 _PyWstrList env_warnoptions = _PyWstrList_INIT;
2180
Victor Stinnerae239f62019-05-16 17:02:56 +02002181 if (config->parse_argv < 0) {
2182 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002183 }
Victor Stinner870b0352019-05-17 03:15:12 +02002184
Victor Stinnerfed02e12019-05-17 11:12:09 +02002185 if (config->program_name == NULL) {
2186 err = config_init_program_name(config);
Victor Stinner870b0352019-05-17 03:15:12 +02002187 if (_Py_INIT_FAILED(err)) {
Victor Stinnerfed02e12019-05-17 11:12:09 +02002188 return err;
Victor Stinner870b0352019-05-17 03:15:12 +02002189 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002190 }
Victor Stinner2f549082019-03-29 15:13:46 +01002191
Victor Stinnerae239f62019-05-16 17:02:56 +02002192 if (config->parse_argv) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002193 Py_ssize_t opt_index;
Victor Stinner870b0352019-05-17 03:15:12 +02002194 err = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
Victor Stinnerae239f62019-05-16 17:02:56 +02002195 if (_Py_INIT_FAILED(err)) {
2196 goto done;
2197 }
2198
Victor Stinner870b0352019-05-17 03:15:12 +02002199 err = config_update_argv(config, opt_index);
Victor Stinnerae239f62019-05-16 17:02:56 +02002200 if (_Py_INIT_FAILED(err)) {
2201 goto done;
2202 }
Victor Stinner2f549082019-03-29 15:13:46 +01002203 }
2204
Victor Stinner2f549082019-03-29 15:13:46 +01002205 if (config->use_environment) {
2206 err = config_init_env_warnoptions(config, &env_warnoptions);
2207 if (_Py_INIT_FAILED(err)) {
2208 goto done;
2209 }
2210 }
2211
2212 err = config_init_warnoptions(config,
2213 &cmdline_warnoptions, &env_warnoptions);
2214 if (_Py_INIT_FAILED(err)) {
2215 goto done;
2216 }
2217
2218 err = _Py_INIT_OK();
2219
2220done:
2221 _PyWstrList_Clear(&cmdline_warnoptions);
2222 _PyWstrList_Clear(&env_warnoptions);
2223 return err;
2224}
2225
2226
Victor Stinner5f38b842019-05-01 02:30:12 +02002227_PyInitError
2228_PyCoreConfig_SetPyArgv(_PyCoreConfig *config, const _PyArgv *args)
2229{
Victor Stinner6d1c4672019-05-20 11:02:00 +02002230 _PyInitError err = _Py_PreInitializeFromCoreConfig(config, args);
2231 if (_Py_INIT_FAILED(err)) {
2232 return err;
Victor Stinner70005ac2019-05-02 15:25:34 -04002233 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002234
Victor Stinner5f38b842019-05-01 02:30:12 +02002235 return _PyArgv_AsWstrList(args, &config->argv);
2236}
2237
2238
Victor Stinner70005ac2019-05-02 15:25:34 -04002239/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2240 if needed to ensure that encodings are properly configured. */
Victor Stinner5f38b842019-05-01 02:30:12 +02002241_PyInitError
Victor Stinner6d1c4672019-05-20 11:02:00 +02002242_PyCoreConfig_SetArgv(_PyCoreConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002243{
2244 _PyArgv args = {
2245 .argc = argc,
2246 .use_bytes_argv = 1,
2247 .bytes_argv = argv,
2248 .wchar_argv = NULL};
2249 return _PyCoreConfig_SetPyArgv(config, &args);
2250}
2251
2252
2253_PyInitError
Victor Stinner6d1c4672019-05-20 11:02:00 +02002254_PyCoreConfig_SetWideArgv(_PyCoreConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002255{
2256 _PyArgv args = {
2257 .argc = argc,
2258 .use_bytes_argv = 0,
2259 .bytes_argv = NULL,
2260 .wchar_argv = argv};
2261 return _PyCoreConfig_SetPyArgv(config, &args);
2262}
2263
2264
Victor Stinner4fffd382019-03-06 01:44:31 +01002265/* Read the configuration into _PyCoreConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002266
2267 * Command line arguments
2268 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002269 * Py_xxx global configuration variables
2270
2271 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002272_PyInitError
Victor Stinner5f38b842019-05-01 02:30:12 +02002273_PyCoreConfig_Read(_PyCoreConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002274{
2275 _PyInitError err;
Victor Stinnercab5d072019-05-17 19:01:14 +02002276 _PyWstrList orig_argv = _PyWstrList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002277
Victor Stinner70005ac2019-05-02 15:25:34 -04002278 err = _Py_PreInitializeFromCoreConfig(config, NULL);
Victor Stinner6d5ee972019-03-23 12:05:43 +01002279 if (_Py_INIT_FAILED(err)) {
2280 return err;
2281 }
2282
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002283 _PyCoreConfig_GetGlobalConfig(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002284
Victor Stinnercab5d072019-05-17 19:01:14 +02002285 if (_PyWstrList_Copy(&orig_argv, &config->argv) < 0) {
2286 return _Py_INIT_NO_MEMORY();
2287 }
2288
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002289 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner5f38b842019-05-01 02:30:12 +02002290 err = core_read_precmdline(config, &precmdline);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002291 if (_Py_INIT_FAILED(err)) {
2292 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002293 }
2294
Victor Stinner870b0352019-05-17 03:15:12 +02002295 assert(config->isolated >= 0);
2296 if (config->isolated) {
2297 config->use_environment = 0;
2298 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002299 }
2300
Victor Stinner870b0352019-05-17 03:15:12 +02002301 err = config_read_cmdline(config);
2302 if (_Py_INIT_FAILED(err)) {
2303 goto done;
2304 }
2305
2306 err = config_read(config);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002307 if (_Py_INIT_FAILED(err)) {
2308 goto done;
2309 }
2310
Victor Stinnercab5d072019-05-17 19:01:14 +02002311 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002312 err = _Py_INIT_NO_MEMORY();
2313 goto done;
2314 }
2315
2316 /* Check config consistency */
2317 assert(config->isolated >= 0);
2318 assert(config->use_environment >= 0);
2319 assert(config->dev_mode >= 0);
2320 assert(config->install_signal_handlers >= 0);
2321 assert(config->use_hash_seed >= 0);
2322 assert(config->faulthandler >= 0);
2323 assert(config->tracemalloc >= 0);
2324 assert(config->site_import >= 0);
2325 assert(config->bytes_warning >= 0);
2326 assert(config->inspect >= 0);
2327 assert(config->interactive >= 0);
2328 assert(config->optimization_level >= 0);
2329 assert(config->parser_debug >= 0);
2330 assert(config->write_bytecode >= 0);
2331 assert(config->verbose >= 0);
2332 assert(config->quiet >= 0);
2333 assert(config->user_site_directory >= 0);
Victor Stinnerae239f62019-05-16 17:02:56 +02002334 assert(config->parse_argv >= 0);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002335 assert(config->configure_c_stdio >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002336 assert(config->buffered_stdio >= 0);
2337 assert(config->program_name != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002338 assert(_PyWstrList_CheckConsistency(&config->argv));
Victor Stinner54b43bb2019-05-16 18:30:15 +02002339 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2340 assert(config->argv.length >= 1);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002341 assert(_PyWstrList_CheckConsistency(&config->xoptions));
2342 assert(_PyWstrList_CheckConsistency(&config->warnoptions));
2343 assert(_PyWstrList_CheckConsistency(&config->module_search_paths));
2344 if (config->_install_importlib) {
Victor Stinner54b43bb2019-05-16 18:30:15 +02002345 assert(config->use_module_search_paths != 0);
2346 /* don't check config->module_search_paths */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002347 assert(config->executable != NULL);
2348 assert(config->prefix != NULL);
2349 assert(config->base_prefix != NULL);
2350 assert(config->exec_prefix != NULL);
2351 assert(config->base_exec_prefix != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002352 }
2353 assert(config->filesystem_encoding != NULL);
2354 assert(config->filesystem_errors != NULL);
2355 assert(config->stdio_encoding != NULL);
2356 assert(config->stdio_errors != NULL);
2357#ifdef MS_WINDOWS
2358 assert(config->legacy_windows_stdio >= 0);
2359#endif
Victor Stinnerae239f62019-05-16 17:02:56 +02002360 /* -c and -m options are exclusive */
2361 assert(!(config->run_command != NULL && config->run_module != NULL));
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002362 assert(config->check_hash_pycs_mode != NULL);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002363 assert(config->_install_importlib >= 0);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02002364 assert(config->pathconfig_warnings >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002365
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002366 err = _Py_INIT_OK();
2367
2368done:
Victor Stinnercab5d072019-05-17 19:01:14 +02002369 _PyWstrList_Clear(&orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002370 _PyPreCmdline_Clear(&precmdline);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002371 return err;
2372}
Victor Stinner1075d162019-03-25 23:19:57 +01002373
2374
2375PyObject*
2376_Py_GetConfigsAsDict(void)
2377{
2378 PyObject *config = NULL;
2379 PyObject *dict = NULL;
2380
2381 config = PyDict_New();
2382 if (config == NULL) {
2383 goto error;
2384 }
2385
2386 /* global config */
2387 dict = _Py_GetGlobalVariablesAsDict();
2388 if (dict == NULL) {
2389 goto error;
2390 }
2391 if (PyDict_SetItemString(config, "global_config", dict) < 0) {
2392 goto error;
2393 }
2394 Py_CLEAR(dict);
2395
2396 /* pre config */
2397 PyInterpreterState *interp = _PyInterpreterState_Get();
Victor Stinner20004952019-03-26 02:31:11 +01002398 const _PyPreConfig *pre_config = &_PyRuntime.preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002399 dict = _PyPreConfig_AsDict(pre_config);
2400 if (dict == NULL) {
2401 goto error;
2402 }
2403 if (PyDict_SetItemString(config, "pre_config", dict) < 0) {
2404 goto error;
2405 }
2406 Py_CLEAR(dict);
2407
2408 /* core config */
Victor Stinner20004952019-03-26 02:31:11 +01002409 const _PyCoreConfig *core_config = _PyInterpreterState_GetCoreConfig(interp);
Victor Stinner1075d162019-03-25 23:19:57 +01002410 dict = _PyCoreConfig_AsDict(core_config);
2411 if (dict == NULL) {
2412 goto error;
2413 }
2414 if (PyDict_SetItemString(config, "core_config", dict) < 0) {
2415 goto error;
2416 }
2417 Py_CLEAR(dict);
2418
Victor Stinner1075d162019-03-25 23:19:57 +01002419 return config;
2420
2421error:
2422 Py_XDECREF(config);
2423 Py_XDECREF(dict);
2424 return NULL;
2425}