Branch data Line data Source code
1 : : #include "Python.h"
2 : : #include "pycore_fileutils.h" // _Py_HasFileSystemDefaultEncodeErrors
3 : : #include "pycore_getopt.h" // _PyOS_GetOpt()
4 : : #include "pycore_initconfig.h" // _PyStatus_OK()
5 : : #include "pycore_interp.h" // _PyInterpreterState.runtime
6 : : #include "pycore_pathconfig.h" // _Py_path_config
7 : : #include "pycore_pyerrors.h" // _PyErr_Fetch()
8 : : #include "pycore_pylifecycle.h" // _Py_PreInitializeFromConfig()
9 : : #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
10 : : #include "pycore_pystate.h" // _PyThreadState_GET()
11 : :
12 : : #include "osdefs.h" // DELIM
13 : :
14 : : #include <locale.h> // setlocale()
15 : : #include <stdlib.h> // getenv()
16 : : #if defined(MS_WINDOWS) || defined(__CYGWIN__)
17 : : # ifdef HAVE_IO_H
18 : : # include <io.h>
19 : : # endif
20 : : # ifdef HAVE_FCNTL_H
21 : : # include <fcntl.h> // O_BINARY
22 : : # endif
23 : : #endif
24 : :
25 : : /* --- Command line options --------------------------------------- */
26 : :
27 : : /* Short usage message (with %s for argv0) */
28 : : static const char usage_line[] =
29 : : "usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
30 : :
31 : : /* Long help message */
32 : : /* Lines sorted by option name; keep in sync with usage_envvars* below */
33 : : static const char usage_help[] = "\
34 : : Options (and corresponding environment variables):\n\
35 : : -b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
36 : : and comparing bytes/bytearray with str. (-bb: issue errors)\n\
37 : : -B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
38 : : -c cmd : program passed in as string (terminates option list)\n\
39 : : -d : turn on parser debugging output (for experts only, only works on\n\
40 : : debug builds); also PYTHONDEBUG=x\n\
41 : : -E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
42 : : -h : print this help message and exit (also -? or --help)\n\
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 : : -P : don't prepend a potentially unsafe path to sys.path\n\
52 : : -q : don't print version and copyright messages on interactive startup\n\
53 : : -s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
54 : : -S : don't imply 'import site' on initialization\n\
55 : : -u : force the stdout and stderr streams to be unbuffered;\n\
56 : : this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
57 : : -v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
58 : : can be supplied multiple times to increase verbosity\n\
59 : : -V : print the Python version number and exit (also --version)\n\
60 : : when given twice, print more information about the build\n\
61 : : -W arg : warning control; arg is action:message:category:module:lineno\n\
62 : : also PYTHONWARNINGS=arg\n\
63 : : -x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
64 : : -X opt : set implementation-specific option\n\
65 : : --check-hash-based-pycs always|default|never:\n\
66 : : control how Python invalidates hash-based .pyc files\n\
67 : : --help-env : print help about Python environment variables and exit\n\
68 : : --help-xoptions : print help about implementation-specific -X options and exit\n\
69 : : --help-all : print complete help information and exit\n\
70 : : Arguments:\n\
71 : : file : program read from script file\n\
72 : : - : program read from stdin (default; interactive mode if a tty)\n\
73 : : arg ...: arguments passed to program in sys.argv[1:]\n\
74 : : ";
75 : :
76 : : static const char usage_xoptions[] = "\
77 : : The following implementation-specific options are available:\n\
78 : : \n\
79 : : -X faulthandler: enable faulthandler\n\
80 : : \n\
81 : : -X showrefcount: output the total reference count and number of used\n\
82 : : memory blocks when the program finishes or after each statement in the\n\
83 : : interactive interpreter. This only works on debug builds\n\
84 : : \n\
85 : : -X tracemalloc: start tracing Python memory allocations using the\n\
86 : : tracemalloc module. By default, only the most recent frame is stored in a\n\
87 : : traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\
88 : : traceback limit of NFRAME frames\n\
89 : : \n\
90 : : -X importtime: show how long each import takes. It shows module name,\n\
91 : : cumulative time (including nested imports) and self time (excluding\n\
92 : : nested imports). Note that its output may be broken in multi-threaded\n\
93 : : application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
94 : : \n\
95 : : -X dev: enable CPython's \"development mode\", introducing additional runtime\n\
96 : : checks which are too expensive to be enabled by default. Effect of the\n\
97 : : developer mode:\n\
98 : : * Add default warning filter, as -W default\n\
99 : : * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks()\n\
100 : : C function\n\
101 : : * Enable the faulthandler module to dump the Python traceback on a crash\n\
102 : : * Enable asyncio debug mode\n\
103 : : * Set the dev_mode attribute of sys.flags to True\n\
104 : : * io.IOBase destructor logs close() exceptions\n\
105 : : \n\
106 : : -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\
107 : : locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\
108 : : otherwise activate automatically)\n\
109 : : \n\
110 : : -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
111 : : given directory instead of to the code tree\n\
112 : : \n\
113 : : -X warn_default_encoding: enable opt-in EncodingWarning for 'encoding=None'\n\
114 : : \n\
115 : : -X no_debug_ranges: disable the inclusion of the tables mapping extra location \n\
116 : : information (end line, start column offset and end column offset) to every \n\
117 : : instruction in code objects. This is useful when smaller code objects and pyc \n\
118 : : files are desired as well as suppressing the extra visual location indicators \n\
119 : : when the interpreter displays tracebacks.\n\
120 : : \n\
121 : : -X frozen_modules=[on|off]: whether or not frozen modules should be used.\n\
122 : : The default is \"on\" (or \"off\" if you are running a local build).";
123 : :
124 : : /* Envvars that don't have equivalent command-line options are listed first */
125 : : static const char usage_envvars[] =
126 : : "Environment variables that change behavior:\n"
127 : : "PYTHONSTARTUP: file executed on interactive startup (no default)\n"
128 : : "PYTHONPATH : '%lc'-separated list of directories prefixed to the\n"
129 : : " default module search path. The result is sys.path.\n"
130 : : "PYTHONSAFEPATH: don't prepend a potentially unsafe path to sys.path.\n"
131 : : "PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
132 : : " The default module search path uses %s.\n"
133 : : "PYTHONPLATLIBDIR : override sys.platlibdir.\n"
134 : : "PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
135 : : "PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
136 : : "PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
137 : : "PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n"
138 : : "PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
139 : : " to seed the hashes of str and bytes objects. It can also be set to an\n"
140 : : " integer in the range [0,4294967295] to get hash values with a\n"
141 : : " predictable seed.\n"
142 : : "PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
143 : : " on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
144 : : " hooks.\n"
145 : : "PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
146 : : " coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
147 : : " locale coercion and locale compatibility warnings on stderr.\n"
148 : : "PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
149 : : " debugger. It can be set to the callable of your debugger of choice.\n"
150 : : "PYTHONDEVMODE: enable the development mode.\n"
151 : : "PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n"
152 : : "PYTHONWARNDEFAULTENCODING: enable opt-in EncodingWarning for 'encoding=None'.\n"
153 : : "PYTHONNODEBUGRANGES: If this variable is set, it disables the inclusion of the \n"
154 : : " tables mapping extra location information (end line, start column offset \n"
155 : : " and end column offset) to every instruction in code objects. This is useful \n"
156 : : " when smaller code objects and pyc files are desired as well as suppressing the \n"
157 : : " extra visual location indicators when the interpreter displays tracebacks.\n"
158 : : "These variables have equivalent command-line parameters (see --help for details):\n"
159 : : "PYTHONDEBUG : enable parser debug mode (-d)\n"
160 : : "PYTHONDONTWRITEBYTECODE : don't write .pyc files (-B)\n"
161 : : "PYTHONINSPECT : inspect interactively after running script (-i)\n"
162 : : "PYTHONNOUSERSITE : disable user site directory (-s)\n"
163 : : "PYTHONOPTIMIZE : enable level 1 optimizations (-O)\n"
164 : : "PYTHONUNBUFFERED : disable stdout/stderr buffering (-u)\n"
165 : : "PYTHONVERBOSE : trace import statements (-v)\n"
166 : : "PYTHONWARNINGS=arg : warning control (-W arg)\n";
167 : :
168 : : #if defined(MS_WINDOWS)
169 : : # define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
170 : : #else
171 : : # define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
172 : : #endif
173 : :
174 : :
175 : : /* --- Global configuration variables ----------------------------- */
176 : :
177 : : /* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
178 : : stdin and stdout error handler to "surrogateescape". */
179 : : int Py_UTF8Mode = 0;
180 : : int Py_DebugFlag = 0; /* Needed by parser.c */
181 : : int Py_VerboseFlag = 0; /* Needed by import.c */
182 : : int Py_QuietFlag = 0; /* Needed by sysmodule.c */
183 : : int Py_InteractiveFlag = 0; /* Previously, was used by Py_FdIsInteractive() */
184 : : int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
185 : : int Py_OptimizeFlag = 0; /* Needed by compile.c */
186 : : int Py_NoSiteFlag = 0; /* Suppress 'import site' */
187 : : int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
188 : : int Py_FrozenFlag = 0; /* Needed by getpath.c */
189 : : int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
190 : : int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
191 : : int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
192 : : int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
193 : : int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
194 : : int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
195 : : #ifdef MS_WINDOWS
196 : : int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
197 : : int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
198 : : #endif
199 : :
200 : :
201 : : static PyObject *
202 : 41 : _Py_GetGlobalVariablesAsDict(void)
203 : : {
204 : : _Py_COMP_DIAG_PUSH
205 : : _Py_COMP_DIAG_IGNORE_DEPR_DECLS
206 : : PyObject *dict, *obj;
207 : :
208 : 41 : dict = PyDict_New();
209 [ - + ]: 41 : if (dict == NULL) {
210 : 0 : return NULL;
211 : : }
212 : :
213 : : #define SET_ITEM(KEY, EXPR) \
214 : : do { \
215 : : obj = (EXPR); \
216 : : if (obj == NULL) { \
217 : : return NULL; \
218 : : } \
219 : : int res = PyDict_SetItemString(dict, (KEY), obj); \
220 : : Py_DECREF(obj); \
221 : : if (res < 0) { \
222 : : goto fail; \
223 : : } \
224 : : } while (0)
225 : : #define SET_ITEM_INT(VAR) \
226 : : SET_ITEM(#VAR, PyLong_FromLong(VAR))
227 : : #define FROM_STRING(STR) \
228 : : ((STR != NULL) ? \
229 : : PyUnicode_FromString(STR) \
230 : : : (Py_INCREF(Py_None), Py_None))
231 : : #define SET_ITEM_STR(VAR) \
232 : : SET_ITEM(#VAR, FROM_STRING(VAR))
233 : :
234 [ + - - + : 41 : SET_ITEM_STR(Py_FileSystemDefaultEncoding);
- + ]
235 [ - + - + ]: 41 : SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
236 [ + - - + : 41 : SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
- + ]
237 [ - + - + ]: 41 : SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
238 : :
239 [ - + - + ]: 41 : SET_ITEM_INT(Py_UTF8Mode);
240 [ - + - + ]: 41 : SET_ITEM_INT(Py_DebugFlag);
241 [ - + - + ]: 41 : SET_ITEM_INT(Py_VerboseFlag);
242 [ - + - + ]: 41 : SET_ITEM_INT(Py_QuietFlag);
243 [ - + - + ]: 41 : SET_ITEM_INT(Py_InteractiveFlag);
244 [ - + - + ]: 41 : SET_ITEM_INT(Py_InspectFlag);
245 : :
246 [ - + - + ]: 41 : SET_ITEM_INT(Py_OptimizeFlag);
247 [ - + - + ]: 41 : SET_ITEM_INT(Py_NoSiteFlag);
248 [ - + - + ]: 41 : SET_ITEM_INT(Py_BytesWarningFlag);
249 [ - + - + ]: 41 : SET_ITEM_INT(Py_FrozenFlag);
250 [ - + - + ]: 41 : SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
251 [ - + - + ]: 41 : SET_ITEM_INT(Py_DontWriteBytecodeFlag);
252 [ - + - + ]: 41 : SET_ITEM_INT(Py_NoUserSiteDirectory);
253 [ - + - + ]: 41 : SET_ITEM_INT(Py_UnbufferedStdioFlag);
254 [ - + - + ]: 41 : SET_ITEM_INT(Py_HashRandomizationFlag);
255 [ - + - + ]: 41 : SET_ITEM_INT(Py_IsolatedFlag);
256 : :
257 : : #ifdef MS_WINDOWS
258 : : SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
259 : : SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
260 : : #endif
261 : :
262 : 41 : return dict;
263 : :
264 : 0 : fail:
265 : 0 : Py_DECREF(dict);
266 : 0 : return NULL;
267 : :
268 : : #undef FROM_STRING
269 : : #undef SET_ITEM
270 : : #undef SET_ITEM_INT
271 : : #undef SET_ITEM_STR
272 : : _Py_COMP_DIAG_POP
273 : : }
274 : :
275 : : char*
276 : 2929 : Py_GETENV(const char *name)
277 : : {
278 : : _Py_COMP_DIAG_PUSH
279 : : _Py_COMP_DIAG_IGNORE_DEPR_DECLS
280 [ + + ]: 2929 : if (Py_IgnoreEnvironmentFlag) {
281 : 1864 : return NULL;
282 : : }
283 : 1065 : return getenv(name);
284 : : _Py_COMP_DIAG_POP
285 : : }
286 : :
287 : : /* --- PyStatus ----------------------------------------------- */
288 : :
289 : 0 : PyStatus PyStatus_Ok(void)
290 : 0 : { return _PyStatus_OK(); }
291 : :
292 : 1 : PyStatus PyStatus_Error(const char *err_msg)
293 : : {
294 : : assert(err_msg != NULL);
295 : 1 : return (PyStatus){._type = _PyStatus_TYPE_ERROR,
296 : : .err_msg = err_msg};
297 : : }
298 : :
299 : 0 : PyStatus PyStatus_NoMemory(void)
300 : 0 : { return PyStatus_Error("memory allocation failed"); }
301 : :
302 : 0 : PyStatus PyStatus_Exit(int exitcode)
303 : 0 : { return _PyStatus_EXIT(exitcode); }
304 : :
305 : :
306 : 0 : int PyStatus_IsError(PyStatus status)
307 : 0 : { return _PyStatus_IS_ERROR(status); }
308 : :
309 : 0 : int PyStatus_IsExit(PyStatus status)
310 : 0 : { return _PyStatus_IS_EXIT(status); }
311 : :
312 : 312 : int PyStatus_Exception(PyStatus status)
313 : 312 : { return _PyStatus_EXCEPTION(status); }
314 : :
315 : : PyObject*
316 : 0 : _PyErr_SetFromPyStatus(PyStatus status)
317 : : {
318 [ # # ]: 0 : if (!_PyStatus_IS_ERROR(status)) {
319 : 0 : PyErr_Format(PyExc_SystemError,
320 : : "%s() expects an error PyStatus",
321 : : _PyStatus_GET_FUNC());
322 : : }
323 [ # # ]: 0 : else if (status.func) {
324 : 0 : PyErr_Format(PyExc_ValueError, "%s: %s", status.func, status.err_msg);
325 : : }
326 : : else {
327 : 0 : PyErr_Format(PyExc_ValueError, "%s", status.err_msg);
328 : : }
329 : 0 : return NULL;
330 : : }
331 : :
332 : :
333 : : /* --- PyWideStringList ------------------------------------------------ */
334 : :
335 : : #ifndef NDEBUG
336 : : int
337 : : _PyWideStringList_CheckConsistency(const PyWideStringList *list)
338 : : {
339 : : assert(list->length >= 0);
340 : : if (list->length != 0) {
341 : : assert(list->items != NULL);
342 : : }
343 : : for (Py_ssize_t i = 0; i < list->length; i++) {
344 : : assert(list->items[i] != NULL);
345 : : }
346 : : return 1;
347 : : }
348 : : #endif /* Py_DEBUG */
349 : :
350 : :
351 : : void
352 : 189269 : _PyWideStringList_Clear(PyWideStringList *list)
353 : : {
354 : : assert(_PyWideStringList_CheckConsistency(list));
355 [ + + ]: 419892 : for (Py_ssize_t i=0; i < list->length; i++) {
356 : 230623 : PyMem_RawFree(list->items[i]);
357 : : }
358 : 189269 : PyMem_RawFree(list->items);
359 : 189269 : list->length = 0;
360 : 189269 : list->items = NULL;
361 : 189269 : }
362 : :
363 : :
364 : : int
365 : 59541 : _PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
366 : : {
367 : : assert(_PyWideStringList_CheckConsistency(list));
368 : : assert(_PyWideStringList_CheckConsistency(list2));
369 : :
370 [ + + ]: 59541 : if (list2->length == 0) {
371 : 23617 : _PyWideStringList_Clear(list);
372 : 23617 : return 0;
373 : : }
374 : :
375 : 35924 : PyWideStringList copy = _PyWideStringList_INIT;
376 : :
377 : 35924 : size_t size = list2->length * sizeof(list2->items[0]);
378 : 35924 : copy.items = PyMem_RawMalloc(size);
379 [ - + ]: 35924 : if (copy.items == NULL) {
380 : 0 : return -1;
381 : : }
382 : :
383 [ + + ]: 186742 : for (Py_ssize_t i=0; i < list2->length; i++) {
384 : 150818 : wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
385 [ - + ]: 150818 : if (item == NULL) {
386 : 0 : _PyWideStringList_Clear(©);
387 : 0 : return -1;
388 : : }
389 : 150818 : copy.items[i] = item;
390 : 150818 : copy.length = i + 1;
391 : : }
392 : :
393 : 35924 : _PyWideStringList_Clear(list);
394 : 35924 : *list = copy;
395 : 35924 : return 0;
396 : : }
397 : :
398 : :
399 : : PyStatus
400 : 47707 : PyWideStringList_Insert(PyWideStringList *list,
401 : : Py_ssize_t index, const wchar_t *item)
402 : : {
403 : 47707 : Py_ssize_t len = list->length;
404 [ - + ]: 47707 : if (len == PY_SSIZE_T_MAX) {
405 : : /* length+1 would overflow */
406 : 0 : return _PyStatus_NO_MEMORY();
407 : : }
408 [ - + ]: 47707 : if (index < 0) {
409 : 0 : return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
410 : : }
411 [ - + ]: 47707 : if (index > len) {
412 : 0 : index = len;
413 : : }
414 : :
415 : 47707 : wchar_t *item2 = _PyMem_RawWcsdup(item);
416 [ - + ]: 47707 : if (item2 == NULL) {
417 : 0 : return _PyStatus_NO_MEMORY();
418 : : }
419 : :
420 : 47707 : size_t size = (len + 1) * sizeof(list->items[0]);
421 : 47707 : wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
422 [ - + ]: 47707 : if (items2 == NULL) {
423 : 0 : PyMem_RawFree(item2);
424 : 0 : return _PyStatus_NO_MEMORY();
425 : : }
426 : :
427 [ + + ]: 47707 : if (index < len) {
428 : 1 : memmove(&items2[index + 1],
429 : 1 : &items2[index],
430 : 1 : (len - index) * sizeof(items2[0]));
431 : : }
432 : :
433 : 47707 : items2[index] = item2;
434 : 47707 : list->items = items2;
435 : 47707 : list->length++;
436 : 47707 : return _PyStatus_OK();
437 : : }
438 : :
439 : :
440 : : PyStatus
441 : 47706 : PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
442 : : {
443 : 47706 : return PyWideStringList_Insert(list, list->length, item);
444 : : }
445 : :
446 : :
447 : : PyStatus
448 : 6089 : _PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
449 : : {
450 [ + + ]: 7387 : for (Py_ssize_t i = 0; i < list2->length; i++) {
451 : 1298 : PyStatus status = PyWideStringList_Append(list, list2->items[i]);
452 [ - + ]: 1298 : if (_PyStatus_EXCEPTION(status)) {
453 : 0 : return status;
454 : : }
455 : : }
456 : 6089 : return _PyStatus_OK();
457 : : }
458 : :
459 : :
460 : : static int
461 : 3970 : _PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
462 : : {
463 [ + + ]: 4979 : for (Py_ssize_t i = 0; i < list->length; i++) {
464 [ + + ]: 1013 : if (wcscmp(list->items[i], item) == 0) {
465 : 4 : return 1;
466 : : }
467 : : }
468 : 3966 : return 0;
469 : : }
470 : :
471 : :
472 : : PyObject*
473 : 28997 : _PyWideStringList_AsList(const PyWideStringList *list)
474 : : {
475 : : assert(_PyWideStringList_CheckConsistency(list));
476 : :
477 : 28997 : PyObject *pylist = PyList_New(list->length);
478 [ - + ]: 28997 : if (pylist == NULL) {
479 : 0 : return NULL;
480 : : }
481 : :
482 [ + + ]: 98159 : for (Py_ssize_t i = 0; i < list->length; i++) {
483 : 69162 : PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
484 [ - + ]: 69162 : if (item == NULL) {
485 : 0 : Py_DECREF(pylist);
486 : 0 : return NULL;
487 : : }
488 : 69162 : PyList_SET_ITEM(pylist, i, item);
489 : : }
490 : 28997 : return pylist;
491 : : }
492 : :
493 : :
494 : : /* --- Py_SetStandardStreamEncoding() ----------------------------- */
495 : :
496 : : /* Helper to allow an embedding application to override the normal
497 : : * mechanism that attempts to figure out an appropriate IO encoding
498 : : */
499 : :
500 : : static char *_Py_StandardStreamEncoding = NULL;
501 : : static char *_Py_StandardStreamErrors = NULL;
502 : :
503 : : int
504 : 6 : Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
505 : : {
506 [ + + ]: 6 : if (Py_IsInitialized()) {
507 : : /* This is too late to have any effect */
508 : 1 : return -1;
509 : : }
510 : :
511 : 5 : int res = 0;
512 : :
513 : : /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
514 : : but Py_Initialize() can change the allocator. Use a known allocator
515 : : to be able to release the memory later. */
516 : : PyMemAllocatorEx old_alloc;
517 : 5 : _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
518 : :
519 : : /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
520 : : * initialised yet.
521 : : *
522 : : * However, the raw memory allocators are initialised appropriately
523 : : * as C static variables, so _PyMem_RawStrdup is OK even though
524 : : * Py_Initialize hasn't been called yet.
525 : : */
526 [ + + ]: 5 : if (encoding) {
527 : 3 : PyMem_RawFree(_Py_StandardStreamEncoding);
528 : 3 : _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
529 [ - + ]: 3 : if (!_Py_StandardStreamEncoding) {
530 : 0 : res = -2;
531 : 0 : goto done;
532 : : }
533 : : }
534 [ + + ]: 5 : if (errors) {
535 : 3 : PyMem_RawFree(_Py_StandardStreamErrors);
536 : 3 : _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
537 [ + - ]: 3 : if (!_Py_StandardStreamErrors) {
538 : 0 : PyMem_RawFree(_Py_StandardStreamEncoding);
539 : 0 : _Py_StandardStreamEncoding = NULL;
540 : 0 : res = -3;
541 : 0 : goto done;
542 : : }
543 : : }
544 : : #ifdef MS_WINDOWS
545 : : if (_Py_StandardStreamEncoding) {
546 : : _Py_COMP_DIAG_PUSH
547 : : _Py_COMP_DIAG_IGNORE_DEPR_DECLS
548 : : /* Overriding the stream encoding implies legacy streams */
549 : : Py_LegacyWindowsStdioFlag = 1;
550 : : _Py_COMP_DIAG_POP
551 : : }
552 : : #endif
553 : :
554 : 5 : done:
555 : 5 : PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
556 : :
557 : 5 : return res;
558 : : }
559 : :
560 : :
561 : : void
562 : 5284 : _Py_ClearStandardStreamEncoding(void)
563 : : {
564 : : /* Use the same allocator than Py_SetStandardStreamEncoding() */
565 : : PyMemAllocatorEx old_alloc;
566 : 5284 : _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
567 : :
568 : : /* We won't need them anymore. */
569 [ + + ]: 5284 : if (_Py_StandardStreamEncoding) {
570 : 3 : PyMem_RawFree(_Py_StandardStreamEncoding);
571 : 3 : _Py_StandardStreamEncoding = NULL;
572 : : }
573 [ + + ]: 5284 : if (_Py_StandardStreamErrors) {
574 : 3 : PyMem_RawFree(_Py_StandardStreamErrors);
575 : 3 : _Py_StandardStreamErrors = NULL;
576 : : }
577 : :
578 : 5284 : PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
579 : 5284 : }
580 : :
581 : :
582 : : /* --- Py_GetArgcArgv() ------------------------------------------- */
583 : :
584 : : /* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
585 : : static PyWideStringList orig_argv = {.length = 0, .items = NULL};
586 : :
587 : :
588 : : void
589 : 2152 : _Py_ClearArgcArgv(void)
590 : : {
591 : : PyMemAllocatorEx old_alloc;
592 : 2152 : _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
593 : :
594 : 2152 : _PyWideStringList_Clear(&orig_argv);
595 : :
596 : 2152 : PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
597 : 2152 : }
598 : :
599 : :
600 : : static int
601 : 3011 : _Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
602 : : {
603 : 3011 : const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
604 : : int res;
605 : :
606 : : PyMemAllocatorEx old_alloc;
607 : 3011 : _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
608 : :
609 : 3011 : res = _PyWideStringList_Copy(&orig_argv, &argv_list);
610 : :
611 : 3011 : PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
612 : 3011 : return res;
613 : : }
614 : :
615 : :
616 : : // _PyConfig_Write() calls _Py_SetArgcArgv() with PyConfig.orig_argv.
617 : : void
618 : 1 : Py_GetArgcArgv(int *argc, wchar_t ***argv)
619 : : {
620 : 1 : *argc = (int)orig_argv.length;
621 : 1 : *argv = orig_argv.items;
622 : 1 : }
623 : :
624 : :
625 : : /* --- PyConfig ---------------------------------------------- */
626 : :
627 : : #define MAX_HASH_SEED 4294967295UL
628 : :
629 : :
630 : : #ifndef NDEBUG
631 : : static int
632 : : config_check_consistency(const PyConfig *config)
633 : : {
634 : : /* Check config consistency */
635 : : assert(config->isolated >= 0);
636 : : assert(config->use_environment >= 0);
637 : : assert(config->dev_mode >= 0);
638 : : assert(config->install_signal_handlers >= 0);
639 : : assert(config->use_hash_seed >= 0);
640 : : assert(config->hash_seed <= MAX_HASH_SEED);
641 : : assert(config->faulthandler >= 0);
642 : : assert(config->tracemalloc >= 0);
643 : : assert(config->import_time >= 0);
644 : : assert(config->code_debug_ranges >= 0);
645 : : assert(config->show_ref_count >= 0);
646 : : assert(config->dump_refs >= 0);
647 : : assert(config->malloc_stats >= 0);
648 : : assert(config->site_import >= 0);
649 : : assert(config->bytes_warning >= 0);
650 : : assert(config->warn_default_encoding >= 0);
651 : : assert(config->inspect >= 0);
652 : : assert(config->interactive >= 0);
653 : : assert(config->optimization_level >= 0);
654 : : assert(config->parser_debug >= 0);
655 : : assert(config->write_bytecode >= 0);
656 : : assert(config->verbose >= 0);
657 : : assert(config->quiet >= 0);
658 : : assert(config->user_site_directory >= 0);
659 : : assert(config->parse_argv >= 0);
660 : : assert(config->configure_c_stdio >= 0);
661 : : assert(config->buffered_stdio >= 0);
662 : : assert(_PyWideStringList_CheckConsistency(&config->orig_argv));
663 : : assert(_PyWideStringList_CheckConsistency(&config->argv));
664 : : /* sys.argv must be non-empty: empty argv is replaced with [''] */
665 : : assert(config->argv.length >= 1);
666 : : assert(_PyWideStringList_CheckConsistency(&config->xoptions));
667 : : assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
668 : : assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
669 : : assert(config->module_search_paths_set >= 0);
670 : : assert(config->filesystem_encoding != NULL);
671 : : assert(config->filesystem_errors != NULL);
672 : : assert(config->stdio_encoding != NULL);
673 : : assert(config->stdio_errors != NULL);
674 : : #ifdef MS_WINDOWS
675 : : assert(config->legacy_windows_stdio >= 0);
676 : : #endif
677 : : /* -c and -m options are exclusive */
678 : : assert(!(config->run_command != NULL && config->run_module != NULL));
679 : : assert(config->check_hash_pycs_mode != NULL);
680 : : assert(config->_install_importlib >= 0);
681 : : assert(config->pathconfig_warnings >= 0);
682 : : assert(config->_is_python_build >= 0);
683 : : assert(config->safe_path >= 0);
684 : : // config->use_frozen_modules is initialized later
685 : : // by _PyConfig_InitImportConfig().
686 : : return 1;
687 : : }
688 : : #endif
689 : :
690 : :
691 : : /* Free memory allocated in config, but don't clear all attributes */
692 : : void
693 : 15617 : PyConfig_Clear(PyConfig *config)
694 : : {
695 : : #define CLEAR(ATTR) \
696 : : do { \
697 : : PyMem_RawFree(ATTR); \
698 : : ATTR = NULL; \
699 : : } while (0)
700 : :
701 : 15617 : CLEAR(config->pycache_prefix);
702 : 15617 : CLEAR(config->pythonpath_env);
703 : 15617 : CLEAR(config->home);
704 : 15617 : CLEAR(config->program_name);
705 : :
706 : 15617 : _PyWideStringList_Clear(&config->argv);
707 : 15617 : _PyWideStringList_Clear(&config->warnoptions);
708 : 15617 : _PyWideStringList_Clear(&config->xoptions);
709 : 15617 : _PyWideStringList_Clear(&config->module_search_paths);
710 : 15617 : config->module_search_paths_set = 0;
711 : 15617 : CLEAR(config->stdlib_dir);
712 : :
713 : 15617 : CLEAR(config->executable);
714 : 15617 : CLEAR(config->base_executable);
715 : 15617 : CLEAR(config->prefix);
716 : 15617 : CLEAR(config->base_prefix);
717 : 15617 : CLEAR(config->exec_prefix);
718 : 15617 : CLEAR(config->base_exec_prefix);
719 : 15617 : CLEAR(config->platlibdir);
720 : :
721 : 15617 : CLEAR(config->filesystem_encoding);
722 : 15617 : CLEAR(config->filesystem_errors);
723 : 15617 : CLEAR(config->stdio_encoding);
724 : 15617 : CLEAR(config->stdio_errors);
725 : 15617 : CLEAR(config->run_command);
726 : 15617 : CLEAR(config->run_module);
727 : 15617 : CLEAR(config->run_filename);
728 : 15617 : CLEAR(config->check_hash_pycs_mode);
729 : :
730 : 15617 : _PyWideStringList_Clear(&config->orig_argv);
731 : : #undef CLEAR
732 : 15617 : }
733 : :
734 : :
735 : : void
736 : 9383 : _PyConfig_InitCompatConfig(PyConfig *config)
737 : : {
738 : 9383 : memset(config, 0, sizeof(*config));
739 : :
740 : 9383 : config->_config_init = (int)_PyConfig_INIT_COMPAT;
741 : 9383 : config->isolated = -1;
742 : 9383 : config->use_environment = -1;
743 : 9383 : config->dev_mode = -1;
744 : 9383 : config->install_signal_handlers = 1;
745 : 9383 : config->use_hash_seed = -1;
746 : 9383 : config->faulthandler = -1;
747 : 9383 : config->tracemalloc = -1;
748 : 9383 : config->module_search_paths_set = 0;
749 : 9383 : config->parse_argv = 0;
750 : 9383 : config->site_import = -1;
751 : 9383 : config->bytes_warning = -1;
752 : 9383 : config->warn_default_encoding = 0;
753 : 9383 : config->inspect = -1;
754 : 9383 : config->interactive = -1;
755 : 9383 : config->optimization_level = -1;
756 : 9383 : config->parser_debug= -1;
757 : 9383 : config->write_bytecode = -1;
758 : 9383 : config->verbose = -1;
759 : 9383 : config->quiet = -1;
760 : 9383 : config->user_site_directory = -1;
761 : 9383 : config->configure_c_stdio = 0;
762 : 9383 : config->buffered_stdio = -1;
763 : 9383 : config->_install_importlib = 1;
764 : 9383 : config->check_hash_pycs_mode = NULL;
765 : 9383 : config->pathconfig_warnings = -1;
766 : 9383 : config->_init_main = 1;
767 : 9383 : config->_isolated_interpreter = 0;
768 : : #ifdef MS_WINDOWS
769 : : config->legacy_windows_stdio = -1;
770 : : #endif
771 : : #ifdef Py_DEBUG
772 : : config->use_frozen_modules = 0;
773 : : #else
774 : 9383 : config->use_frozen_modules = 1;
775 : : #endif
776 : 9383 : config->safe_path = 0;
777 : 9383 : config->_is_python_build = 0;
778 : 9383 : config->code_debug_ranges = 1;
779 : 9383 : }
780 : :
781 : :
782 : : static void
783 : 9326 : config_init_defaults(PyConfig *config)
784 : : {
785 : 9326 : _PyConfig_InitCompatConfig(config);
786 : :
787 : 9326 : config->isolated = 0;
788 : 9326 : config->use_environment = 1;
789 : 9326 : config->site_import = 1;
790 : 9326 : config->bytes_warning = 0;
791 : 9326 : config->inspect = 0;
792 : 9326 : config->interactive = 0;
793 : 9326 : config->optimization_level = 0;
794 : 9326 : config->parser_debug= 0;
795 : 9326 : config->write_bytecode = 1;
796 : 9326 : config->verbose = 0;
797 : 9326 : config->quiet = 0;
798 : 9326 : config->user_site_directory = 1;
799 : 9326 : config->buffered_stdio = 1;
800 : 9326 : config->pathconfig_warnings = 1;
801 : : #ifdef MS_WINDOWS
802 : : config->legacy_windows_stdio = 0;
803 : : #endif
804 : 9326 : }
805 : :
806 : :
807 : : void
808 : 9069 : PyConfig_InitPythonConfig(PyConfig *config)
809 : : {
810 : 9069 : config_init_defaults(config);
811 : :
812 : 9069 : config->_config_init = (int)_PyConfig_INIT_PYTHON;
813 : 9069 : config->configure_c_stdio = 1;
814 : 9069 : config->parse_argv = 1;
815 : 9069 : }
816 : :
817 : :
818 : : void
819 : 257 : PyConfig_InitIsolatedConfig(PyConfig *config)
820 : : {
821 : 257 : config_init_defaults(config);
822 : :
823 : 257 : config->_config_init = (int)_PyConfig_INIT_ISOLATED;
824 : 257 : config->isolated = 1;
825 : 257 : config->use_environment = 0;
826 : 257 : config->user_site_directory = 0;
827 : 257 : config->dev_mode = 0;
828 : 257 : config->install_signal_handlers = 0;
829 : 257 : config->use_hash_seed = 0;
830 : 257 : config->faulthandler = 0;
831 : 257 : config->tracemalloc = 0;
832 : 257 : config->safe_path = 1;
833 : 257 : config->pathconfig_warnings = 0;
834 : : #ifdef MS_WINDOWS
835 : : config->legacy_windows_stdio = 0;
836 : : #endif
837 : 257 : }
838 : :
839 : :
840 : : /* Copy str into *config_str (duplicate the string) */
841 : : PyStatus
842 : 204675 : PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
843 : : {
844 : 204675 : PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
845 [ - + ]: 204675 : if (_PyStatus_EXCEPTION(status)) {
846 : 0 : return status;
847 : : }
848 : :
849 : : wchar_t *str2;
850 [ + + ]: 204675 : if (str != NULL) {
851 : 85883 : str2 = _PyMem_RawWcsdup(str);
852 [ - + ]: 85883 : if (str2 == NULL) {
853 : 0 : return _PyStatus_NO_MEMORY();
854 : : }
855 : : }
856 : : else {
857 : 118792 : str2 = NULL;
858 : : }
859 : 204675 : PyMem_RawFree(*config_str);
860 : 204675 : *config_str = str2;
861 : 204675 : return _PyStatus_OK();
862 : : }
863 : :
864 : :
865 : : static PyStatus
866 : 443 : config_set_bytes_string(PyConfig *config, wchar_t **config_str,
867 : : const char *str, const char *decode_err_msg)
868 : : {
869 : 443 : PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
870 [ - + ]: 443 : if (_PyStatus_EXCEPTION(status)) {
871 : 0 : return status;
872 : : }
873 : :
874 : : wchar_t *str2;
875 [ + - ]: 443 : if (str != NULL) {
876 : : size_t len;
877 : 443 : str2 = Py_DecodeLocale(str, &len);
878 [ - + ]: 443 : if (str2 == NULL) {
879 [ # # ]: 0 : if (len == (size_t)-2) {
880 : 0 : return _PyStatus_ERR(decode_err_msg);
881 : : }
882 : : else {
883 : 0 : return _PyStatus_NO_MEMORY();
884 : : }
885 : : }
886 : : }
887 : : else {
888 : 0 : str2 = NULL;
889 : : }
890 : 443 : PyMem_RawFree(*config_str);
891 : 443 : *config_str = str2;
892 : 443 : return _PyStatus_OK();
893 : : }
894 : :
895 : :
896 : : #define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
897 : : config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
898 : :
899 : :
900 : : /* Decode str using Py_DecodeLocale() and set the result into *config_str.
901 : : Pre-initialize Python if needed to ensure that encodings are properly
902 : : configured. */
903 : : PyStatus
904 : 1 : PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
905 : : const char *str)
906 : : {
907 : 1 : return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
908 : : }
909 : :
910 : :
911 : : PyStatus
912 : 6253 : _PyConfig_Copy(PyConfig *config, const PyConfig *config2)
913 : : {
914 : : PyStatus status;
915 : :
916 : 6253 : PyConfig_Clear(config);
917 : :
918 : : #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
919 : : #define COPY_WSTR_ATTR(ATTR) \
920 : : do { \
921 : : status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
922 : : if (_PyStatus_EXCEPTION(status)) { \
923 : : return status; \
924 : : } \
925 : : } while (0)
926 : : #define COPY_WSTRLIST(LIST) \
927 : : do { \
928 : : if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
929 : : return _PyStatus_NO_MEMORY(); \
930 : : } \
931 : : } while (0)
932 : :
933 : 6253 : COPY_ATTR(_config_init);
934 : 6253 : COPY_ATTR(isolated);
935 : 6253 : COPY_ATTR(use_environment);
936 : 6253 : COPY_ATTR(dev_mode);
937 : 6253 : COPY_ATTR(install_signal_handlers);
938 : 6253 : COPY_ATTR(use_hash_seed);
939 : 6253 : COPY_ATTR(hash_seed);
940 : 6253 : COPY_ATTR(_install_importlib);
941 : 6253 : COPY_ATTR(faulthandler);
942 : 6253 : COPY_ATTR(tracemalloc);
943 : 6253 : COPY_ATTR(import_time);
944 : 6253 : COPY_ATTR(code_debug_ranges);
945 : 6253 : COPY_ATTR(show_ref_count);
946 : 6253 : COPY_ATTR(dump_refs);
947 : 6253 : COPY_ATTR(dump_refs_file);
948 : 6253 : COPY_ATTR(malloc_stats);
949 : :
950 [ - + ]: 6253 : COPY_WSTR_ATTR(pycache_prefix);
951 [ - + ]: 6253 : COPY_WSTR_ATTR(pythonpath_env);
952 [ - + ]: 6253 : COPY_WSTR_ATTR(home);
953 [ - + ]: 6253 : COPY_WSTR_ATTR(program_name);
954 : :
955 : 6253 : COPY_ATTR(parse_argv);
956 [ - + ]: 6253 : COPY_WSTRLIST(argv);
957 [ - + ]: 6253 : COPY_WSTRLIST(warnoptions);
958 [ - + ]: 6253 : COPY_WSTRLIST(xoptions);
959 [ - + ]: 6253 : COPY_WSTRLIST(module_search_paths);
960 : 6253 : COPY_ATTR(module_search_paths_set);
961 [ - + ]: 6253 : COPY_WSTR_ATTR(stdlib_dir);
962 : :
963 [ - + ]: 6253 : COPY_WSTR_ATTR(executable);
964 [ - + ]: 6253 : COPY_WSTR_ATTR(base_executable);
965 [ - + ]: 6253 : COPY_WSTR_ATTR(prefix);
966 [ - + ]: 6253 : COPY_WSTR_ATTR(base_prefix);
967 [ - + ]: 6253 : COPY_WSTR_ATTR(exec_prefix);
968 [ - + ]: 6253 : COPY_WSTR_ATTR(base_exec_prefix);
969 [ - + ]: 6253 : COPY_WSTR_ATTR(platlibdir);
970 : :
971 : 6253 : COPY_ATTR(site_import);
972 : 6253 : COPY_ATTR(bytes_warning);
973 : 6253 : COPY_ATTR(warn_default_encoding);
974 : 6253 : COPY_ATTR(inspect);
975 : 6253 : COPY_ATTR(interactive);
976 : 6253 : COPY_ATTR(optimization_level);
977 : 6253 : COPY_ATTR(parser_debug);
978 : 6253 : COPY_ATTR(write_bytecode);
979 : 6253 : COPY_ATTR(verbose);
980 : 6253 : COPY_ATTR(quiet);
981 : 6253 : COPY_ATTR(user_site_directory);
982 : 6253 : COPY_ATTR(configure_c_stdio);
983 : 6253 : COPY_ATTR(buffered_stdio);
984 [ - + ]: 6253 : COPY_WSTR_ATTR(filesystem_encoding);
985 [ - + ]: 6253 : COPY_WSTR_ATTR(filesystem_errors);
986 [ - + ]: 6253 : COPY_WSTR_ATTR(stdio_encoding);
987 [ - + ]: 6253 : COPY_WSTR_ATTR(stdio_errors);
988 : : #ifdef MS_WINDOWS
989 : : COPY_ATTR(legacy_windows_stdio);
990 : : #endif
991 : 6253 : COPY_ATTR(skip_source_first_line);
992 [ - + ]: 6253 : COPY_WSTR_ATTR(run_command);
993 [ - + ]: 6253 : COPY_WSTR_ATTR(run_module);
994 [ - + ]: 6253 : COPY_WSTR_ATTR(run_filename);
995 [ - + ]: 6253 : COPY_WSTR_ATTR(check_hash_pycs_mode);
996 : 6253 : COPY_ATTR(pathconfig_warnings);
997 : 6253 : COPY_ATTR(_init_main);
998 : 6253 : COPY_ATTR(_isolated_interpreter);
999 : 6253 : COPY_ATTR(use_frozen_modules);
1000 : 6253 : COPY_ATTR(safe_path);
1001 [ - + ]: 6253 : COPY_WSTRLIST(orig_argv);
1002 : 6253 : COPY_ATTR(_is_python_build);
1003 : :
1004 : : #undef COPY_ATTR
1005 : : #undef COPY_WSTR_ATTR
1006 : : #undef COPY_WSTRLIST
1007 : 6253 : return _PyStatus_OK();
1008 : : }
1009 : :
1010 : :
1011 : : PyObject *
1012 : 3258 : _PyConfig_AsDict(const PyConfig *config)
1013 : : {
1014 : 3258 : PyObject *dict = PyDict_New();
1015 [ - + ]: 3258 : if (dict == NULL) {
1016 : 0 : return NULL;
1017 : : }
1018 : :
1019 : : #define SET_ITEM(KEY, EXPR) \
1020 : : do { \
1021 : : PyObject *obj = (EXPR); \
1022 : : if (obj == NULL) { \
1023 : : goto fail; \
1024 : : } \
1025 : : int res = PyDict_SetItemString(dict, (KEY), obj); \
1026 : : Py_DECREF(obj); \
1027 : : if (res < 0) { \
1028 : : goto fail; \
1029 : : } \
1030 : : } while (0)
1031 : : #define SET_ITEM_INT(ATTR) \
1032 : : SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
1033 : : #define SET_ITEM_UINT(ATTR) \
1034 : : SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
1035 : : #define FROM_WSTRING(STR) \
1036 : : ((STR != NULL) ? \
1037 : : PyUnicode_FromWideChar(STR, -1) \
1038 : : : (Py_INCREF(Py_None), Py_None))
1039 : : #define SET_ITEM_WSTR(ATTR) \
1040 : : SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
1041 : : #define SET_ITEM_WSTRLIST(LIST) \
1042 : : SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
1043 : :
1044 [ - + - + ]: 3258 : SET_ITEM_INT(_config_init);
1045 [ - + - + ]: 3258 : SET_ITEM_INT(isolated);
1046 [ - + - + ]: 3258 : SET_ITEM_INT(use_environment);
1047 [ - + - + ]: 3258 : SET_ITEM_INT(dev_mode);
1048 [ - + - + ]: 3258 : SET_ITEM_INT(install_signal_handlers);
1049 [ - + - + ]: 3258 : SET_ITEM_INT(use_hash_seed);
1050 [ - + - + ]: 3258 : SET_ITEM_UINT(hash_seed);
1051 [ - + - + ]: 3258 : SET_ITEM_INT(faulthandler);
1052 [ - + - + ]: 3258 : SET_ITEM_INT(tracemalloc);
1053 [ - + - + ]: 3258 : SET_ITEM_INT(import_time);
1054 [ - + - + ]: 3258 : SET_ITEM_INT(code_debug_ranges);
1055 [ - + - + ]: 3258 : SET_ITEM_INT(show_ref_count);
1056 [ - + - + ]: 3258 : SET_ITEM_INT(dump_refs);
1057 [ - + - + ]: 3258 : SET_ITEM_INT(malloc_stats);
1058 [ + - - + : 3258 : SET_ITEM_WSTR(filesystem_encoding);
- + ]
1059 [ + - - + : 3258 : SET_ITEM_WSTR(filesystem_errors);
- + ]
1060 [ + + - + : 3258 : SET_ITEM_WSTR(pycache_prefix);
- + ]
1061 [ + + - + : 3258 : SET_ITEM_WSTR(program_name);
- + ]
1062 [ - + - + ]: 3258 : SET_ITEM_INT(parse_argv);
1063 [ - + - + ]: 3258 : SET_ITEM_WSTRLIST(argv);
1064 [ - + - + ]: 3258 : SET_ITEM_WSTRLIST(xoptions);
1065 [ - + - + ]: 3258 : SET_ITEM_WSTRLIST(warnoptions);
1066 [ + + - + : 3258 : SET_ITEM_WSTR(pythonpath_env);
- + ]
1067 [ + + - + : 3258 : SET_ITEM_WSTR(home);
- + ]
1068 [ - + - + ]: 3258 : SET_ITEM_INT(module_search_paths_set);
1069 [ - + - + ]: 3258 : SET_ITEM_WSTRLIST(module_search_paths);
1070 [ + + - + : 3258 : SET_ITEM_WSTR(stdlib_dir);
- + ]
1071 [ + + - + : 3258 : SET_ITEM_WSTR(executable);
- + ]
1072 [ + + - + : 3258 : SET_ITEM_WSTR(base_executable);
- + ]
1073 [ + + - + : 3258 : SET_ITEM_WSTR(prefix);
- + ]
1074 [ + + - + : 3258 : SET_ITEM_WSTR(base_prefix);
- + ]
1075 [ + + - + : 3258 : SET_ITEM_WSTR(exec_prefix);
- + ]
1076 [ + + - + : 3258 : SET_ITEM_WSTR(base_exec_prefix);
- + ]
1077 [ + + - + : 3258 : SET_ITEM_WSTR(platlibdir);
- + ]
1078 [ - + - + ]: 3258 : SET_ITEM_INT(site_import);
1079 [ - + - + ]: 3258 : SET_ITEM_INT(bytes_warning);
1080 [ - + - + ]: 3258 : SET_ITEM_INT(warn_default_encoding);
1081 [ - + - + ]: 3258 : SET_ITEM_INT(inspect);
1082 [ - + - + ]: 3258 : SET_ITEM_INT(interactive);
1083 [ - + - + ]: 3258 : SET_ITEM_INT(optimization_level);
1084 [ - + - + ]: 3258 : SET_ITEM_INT(parser_debug);
1085 [ - + - + ]: 3258 : SET_ITEM_INT(write_bytecode);
1086 [ - + - + ]: 3258 : SET_ITEM_INT(verbose);
1087 [ - + - + ]: 3258 : SET_ITEM_INT(quiet);
1088 [ - + - + ]: 3258 : SET_ITEM_INT(user_site_directory);
1089 [ - + - + ]: 3258 : SET_ITEM_INT(configure_c_stdio);
1090 [ - + - + ]: 3258 : SET_ITEM_INT(buffered_stdio);
1091 [ + - - + : 3258 : SET_ITEM_WSTR(stdio_encoding);
- + ]
1092 [ + - - + : 3258 : SET_ITEM_WSTR(stdio_errors);
- + ]
1093 : : #ifdef MS_WINDOWS
1094 : : SET_ITEM_INT(legacy_windows_stdio);
1095 : : #endif
1096 [ - + - + ]: 3258 : SET_ITEM_INT(skip_source_first_line);
1097 [ + + - + : 3258 : SET_ITEM_WSTR(run_command);
- + ]
1098 [ + + - + : 3258 : SET_ITEM_WSTR(run_module);
- + ]
1099 [ + + - + : 3258 : SET_ITEM_WSTR(run_filename);
- + ]
1100 [ - + - + ]: 3258 : SET_ITEM_INT(_install_importlib);
1101 [ + - - + : 3258 : SET_ITEM_WSTR(check_hash_pycs_mode);
- + ]
1102 [ - + - + ]: 3258 : SET_ITEM_INT(pathconfig_warnings);
1103 [ - + - + ]: 3258 : SET_ITEM_INT(_init_main);
1104 [ - + - + ]: 3258 : SET_ITEM_INT(_isolated_interpreter);
1105 [ - + - + ]: 3258 : SET_ITEM_WSTRLIST(orig_argv);
1106 [ - + - + ]: 3258 : SET_ITEM_INT(use_frozen_modules);
1107 [ - + - + ]: 3258 : SET_ITEM_INT(safe_path);
1108 [ - + - + ]: 3258 : SET_ITEM_INT(_is_python_build);
1109 : :
1110 : 3258 : return dict;
1111 : :
1112 : 0 : fail:
1113 : 0 : Py_DECREF(dict);
1114 : 0 : return NULL;
1115 : :
1116 : : #undef FROM_WSTRING
1117 : : #undef SET_ITEM
1118 : : #undef SET_ITEM_INT
1119 : : #undef SET_ITEM_UINT
1120 : : #undef SET_ITEM_WSTR
1121 : : #undef SET_ITEM_WSTRLIST
1122 : : }
1123 : :
1124 : :
1125 : : static PyObject*
1126 : 203114 : config_dict_get(PyObject *dict, const char *name)
1127 : : {
1128 : 203114 : PyObject *item = _PyDict_GetItemStringWithError(dict, name);
1129 [ - + - - ]: 203114 : if (item == NULL && !PyErr_Occurred()) {
1130 : 0 : PyErr_Format(PyExc_ValueError, "missing config key: %s", name);
1131 : 0 : return NULL;
1132 : : }
1133 : 203114 : return item;
1134 : : }
1135 : :
1136 : :
1137 : : static void
1138 : 48 : config_dict_invalid_value(const char *name)
1139 : : {
1140 : 48 : PyErr_Format(PyExc_ValueError, "invalid config value: %s", name);
1141 : 48 : }
1142 : :
1143 : :
1144 : : static void
1145 : 98 : config_dict_invalid_type(const char *name)
1146 : : {
1147 : 98 : PyErr_Format(PyExc_TypeError, "invalid config type: %s", name);
1148 : 98 : }
1149 : :
1150 : :
1151 : : static int
1152 : 118372 : config_dict_get_int(PyObject *dict, const char *name, int *result)
1153 : : {
1154 : 118372 : PyObject *item = config_dict_get(dict, name);
1155 [ - + ]: 118372 : if (item == NULL) {
1156 : 0 : return -1;
1157 : : }
1158 : 118372 : int value = _PyLong_AsInt(item);
1159 [ + + + + ]: 118372 : if (value == -1 && PyErr_Occurred()) {
1160 [ + - ]: 64 : if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1161 : 64 : config_dict_invalid_type(name);
1162 : : }
1163 [ # # ]: 0 : else if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
1164 : 0 : config_dict_invalid_value(name);
1165 : : }
1166 : 64 : return -1;
1167 : : }
1168 : 118308 : *result = value;
1169 : 118308 : return 0;
1170 : : }
1171 : :
1172 : :
1173 : : static int
1174 : 3343 : config_dict_get_ulong(PyObject *dict, const char *name, unsigned long *result)
1175 : : {
1176 : 3343 : PyObject *item = config_dict_get(dict, name);
1177 [ - + ]: 3343 : if (item == NULL) {
1178 : 0 : return -1;
1179 : : }
1180 : 3343 : unsigned long value = PyLong_AsUnsignedLong(item);
1181 [ + + + - ]: 3343 : if (value == (unsigned long)-1 && PyErr_Occurred()) {
1182 [ - + ]: 1 : if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1183 : 0 : config_dict_invalid_type(name);
1184 : : }
1185 [ + - ]: 1 : else if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
1186 : 1 : config_dict_invalid_value(name);
1187 : : }
1188 : 1 : return -1;
1189 : : }
1190 : 3342 : *result = value;
1191 : 3342 : return 0;
1192 : : }
1193 : :
1194 : :
1195 : : static int
1196 : 64951 : config_dict_get_wstr(PyObject *dict, const char *name, PyConfig *config,
1197 : : wchar_t **result)
1198 : : {
1199 : 64951 : PyObject *item = config_dict_get(dict, name);
1200 [ - + ]: 64951 : if (item == NULL) {
1201 : 0 : return -1;
1202 : : }
1203 : : PyStatus status;
1204 [ + + ]: 64951 : if (item == Py_None) {
1205 : 16330 : status = PyConfig_SetString(config, result, NULL);
1206 : : }
1207 [ + + ]: 48621 : else if (!PyUnicode_Check(item)) {
1208 : 14 : config_dict_invalid_type(name);
1209 : 14 : return -1;
1210 : : }
1211 : : else {
1212 : 48607 : wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL);
1213 [ - + ]: 48607 : if (wstr == NULL) {
1214 : 0 : return -1;
1215 : : }
1216 : 48607 : status = PyConfig_SetString(config, result, wstr);
1217 : 48607 : PyMem_Free(wstr);
1218 : : }
1219 [ - + ]: 64937 : if (_PyStatus_EXCEPTION(status)) {
1220 : : PyErr_NoMemory();
1221 : 0 : return -1;
1222 : : }
1223 : 64937 : return 0;
1224 : : }
1225 : :
1226 : :
1227 : : static int
1228 : 16448 : config_dict_get_wstrlist(PyObject *dict, const char *name, PyConfig *config,
1229 : : PyWideStringList *result)
1230 : : {
1231 : 16448 : PyObject *list = config_dict_get(dict, name);
1232 [ - + ]: 16448 : if (list == NULL) {
1233 : 0 : return -1;
1234 : : }
1235 : :
1236 [ + + ]: 16448 : if (!PyList_CheckExact(list)) {
1237 : 10 : config_dict_invalid_type(name);
1238 : 10 : return -1;
1239 : : }
1240 : :
1241 : 16438 : PyWideStringList wstrlist = _PyWideStringList_INIT;
1242 [ + + ]: 57030 : for (Py_ssize_t i=0; i < PyList_GET_SIZE(list); i++) {
1243 : 40607 : PyObject *item = PyList_GET_ITEM(list, i);
1244 : :
1245 [ + + ]: 40607 : if (item == Py_None) {
1246 : 5 : config_dict_invalid_value(name);
1247 : 15 : goto error;
1248 : : }
1249 [ + + ]: 40602 : else if (!PyUnicode_Check(item)) {
1250 : 10 : config_dict_invalid_type(name);
1251 : 10 : goto error;
1252 : : }
1253 : 40592 : wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL);
1254 [ - + ]: 40592 : if (wstr == NULL) {
1255 : 0 : goto error;
1256 : : }
1257 : 40592 : PyStatus status = PyWideStringList_Append(&wstrlist, wstr);
1258 : 40592 : PyMem_Free(wstr);
1259 [ - + ]: 40592 : if (_PyStatus_EXCEPTION(status)) {
1260 : : PyErr_NoMemory();
1261 : 0 : goto error;
1262 : : }
1263 : : }
1264 : :
1265 [ - + ]: 16423 : if (_PyWideStringList_Copy(result, &wstrlist) < 0) {
1266 : : PyErr_NoMemory();
1267 : 0 : goto error;
1268 : : }
1269 : 16423 : _PyWideStringList_Clear(&wstrlist);
1270 : 16423 : return 0;
1271 : :
1272 : 15 : error:
1273 : 15 : _PyWideStringList_Clear(&wstrlist);
1274 : 15 : return -1;
1275 : : }
1276 : :
1277 : :
1278 : : int
1279 : 3363 : _PyConfig_FromDict(PyConfig *config, PyObject *dict)
1280 : : {
1281 [ - + ]: 3363 : if (!PyDict_Check(dict)) {
1282 : 0 : PyErr_SetString(PyExc_TypeError, "dict expected");
1283 : 0 : return -1;
1284 : : }
1285 : :
1286 : : #define CHECK_VALUE(NAME, TEST) \
1287 : : if (!(TEST)) { \
1288 : : config_dict_invalid_value(NAME); \
1289 : : return -1; \
1290 : : }
1291 : : #define GET_UINT(KEY) \
1292 : : do { \
1293 : : if (config_dict_get_int(dict, #KEY, &config->KEY) < 0) { \
1294 : : return -1; \
1295 : : } \
1296 : : CHECK_VALUE(#KEY, config->KEY >= 0); \
1297 : : } while (0)
1298 : : #define GET_WSTR(KEY) \
1299 : : do { \
1300 : : if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \
1301 : : return -1; \
1302 : : } \
1303 : : CHECK_VALUE(#KEY, config->KEY != NULL); \
1304 : : } while (0)
1305 : : #define GET_WSTR_OPT(KEY) \
1306 : : do { \
1307 : : if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \
1308 : : return -1; \
1309 : : } \
1310 : : } while (0)
1311 : : #define GET_WSTRLIST(KEY) \
1312 : : do { \
1313 : : if (config_dict_get_wstrlist(dict, #KEY, config, &config->KEY) < 0) { \
1314 : : return -1; \
1315 : : } \
1316 : : } while (0)
1317 : :
1318 [ + + + + ]: 3363 : GET_UINT(_config_init);
1319 [ + + + + : 3360 : CHECK_VALUE("_config_init",
+ + ]
1320 : : config->_config_init == _PyConfig_INIT_COMPAT
1321 : : || config->_config_init == _PyConfig_INIT_PYTHON
1322 : : || config->_config_init == _PyConfig_INIT_ISOLATED);
1323 [ + + + + ]: 3358 : GET_UINT(isolated);
1324 [ + + + + ]: 3355 : GET_UINT(use_environment);
1325 [ + + + + ]: 3352 : GET_UINT(dev_mode);
1326 [ + + + + ]: 3349 : GET_UINT(install_signal_handlers);
1327 [ + + + + ]: 3346 : GET_UINT(use_hash_seed);
1328 [ + + ]: 3343 : if (config_dict_get_ulong(dict, "hash_seed", &config->hash_seed) < 0) {
1329 : 1 : return -1;
1330 : : }
1331 [ + + ]: 3342 : CHECK_VALUE("hash_seed", config->hash_seed <= MAX_HASH_SEED);
1332 [ + + + + ]: 3341 : GET_UINT(faulthandler);
1333 [ + + + + ]: 3338 : GET_UINT(tracemalloc);
1334 [ + + + + ]: 3335 : GET_UINT(import_time);
1335 [ + + + + ]: 3332 : GET_UINT(code_debug_ranges);
1336 [ + + + + ]: 3329 : GET_UINT(show_ref_count);
1337 [ + + + + ]: 3326 : GET_UINT(dump_refs);
1338 [ + + + + ]: 3323 : GET_UINT(malloc_stats);
1339 [ + + + + ]: 3320 : GET_WSTR(filesystem_encoding);
1340 [ + + + + ]: 3317 : GET_WSTR(filesystem_errors);
1341 [ - + ]: 3314 : GET_WSTR_OPT(pycache_prefix);
1342 [ + + + + ]: 3314 : GET_UINT(parse_argv);
1343 [ + + ]: 3311 : GET_WSTRLIST(orig_argv);
1344 [ + + ]: 3306 : GET_WSTRLIST(argv);
1345 [ + + ]: 3301 : GET_WSTRLIST(xoptions);
1346 [ + + ]: 3296 : GET_WSTRLIST(warnoptions);
1347 [ + + + + ]: 3291 : GET_UINT(site_import);
1348 [ + + + + ]: 3288 : GET_UINT(bytes_warning);
1349 [ - + - + ]: 3285 : GET_UINT(warn_default_encoding);
1350 [ + + + + ]: 3285 : GET_UINT(inspect);
1351 [ + + + + ]: 3282 : GET_UINT(interactive);
1352 [ + + + + ]: 3279 : GET_UINT(optimization_level);
1353 [ + + + + ]: 3276 : GET_UINT(parser_debug);
1354 [ + + + + ]: 3273 : GET_UINT(write_bytecode);
1355 [ + + + + ]: 3270 : GET_UINT(verbose);
1356 [ + + + + ]: 3267 : GET_UINT(quiet);
1357 [ + + + + ]: 3264 : GET_UINT(user_site_directory);
1358 [ + + + + ]: 3261 : GET_UINT(configure_c_stdio);
1359 [ + + + + ]: 3258 : GET_UINT(buffered_stdio);
1360 [ + + + + ]: 3255 : GET_WSTR(stdio_encoding);
1361 [ + + + + ]: 3252 : GET_WSTR(stdio_errors);
1362 : : #ifdef MS_WINDOWS
1363 : : GET_UINT(legacy_windows_stdio);
1364 : : #endif
1365 [ + + + + ]: 3249 : GET_WSTR(check_hash_pycs_mode);
1366 : :
1367 [ + + + + ]: 3246 : GET_UINT(pathconfig_warnings);
1368 [ + + + + ]: 3243 : GET_WSTR(program_name);
1369 [ - + ]: 3240 : GET_WSTR_OPT(pythonpath_env);
1370 [ - + ]: 3240 : GET_WSTR_OPT(home);
1371 [ + + + + ]: 3240 : GET_WSTR(platlibdir);
1372 : :
1373 : : // Path configuration output
1374 [ + + + + ]: 3237 : GET_UINT(module_search_paths_set);
1375 [ + + ]: 3234 : GET_WSTRLIST(module_search_paths);
1376 [ - + ]: 3229 : GET_WSTR_OPT(stdlib_dir);
1377 [ - + ]: 3229 : GET_WSTR_OPT(executable);
1378 [ - + ]: 3229 : GET_WSTR_OPT(base_executable);
1379 [ - + ]: 3229 : GET_WSTR_OPT(prefix);
1380 [ - + ]: 3229 : GET_WSTR_OPT(base_prefix);
1381 [ - + ]: 3229 : GET_WSTR_OPT(exec_prefix);
1382 [ - + ]: 3229 : GET_WSTR_OPT(base_exec_prefix);
1383 : :
1384 [ + + + + ]: 3229 : GET_UINT(skip_source_first_line);
1385 [ - + ]: 3226 : GET_WSTR_OPT(run_command);
1386 [ - + ]: 3226 : GET_WSTR_OPT(run_module);
1387 [ - + ]: 3226 : GET_WSTR_OPT(run_filename);
1388 : :
1389 [ + + + + ]: 3226 : GET_UINT(_install_importlib);
1390 [ + + + + ]: 3223 : GET_UINT(_init_main);
1391 [ + + + + ]: 3220 : GET_UINT(_isolated_interpreter);
1392 [ - + - + ]: 3217 : GET_UINT(use_frozen_modules);
1393 [ - + - + ]: 3217 : GET_UINT(safe_path);
1394 [ - + - + ]: 3217 : GET_UINT(_is_python_build);
1395 : :
1396 : : #undef CHECK_VALUE
1397 : : #undef GET_UINT
1398 : : #undef GET_WSTR
1399 : : #undef GET_WSTR_OPT
1400 : 3217 : return 0;
1401 : : }
1402 : :
1403 : :
1404 : : static const char*
1405 : 19343 : config_get_env(const PyConfig *config, const char *name)
1406 : : {
1407 : 19343 : return _Py_GetEnv(config->use_environment, name);
1408 : : }
1409 : :
1410 : :
1411 : : /* Get a copy of the environment variable as wchar_t*.
1412 : : Return 0 on success, but *dest can be NULL.
1413 : : Return -1 on memory allocation failure. Return -2 on decoding error. */
1414 : : static PyStatus
1415 : 7457 : config_get_env_dup(PyConfig *config,
1416 : : wchar_t **dest,
1417 : : wchar_t *wname, char *name,
1418 : : const char *decode_err_msg)
1419 : : {
1420 : : assert(*dest == NULL);
1421 : : assert(config->use_environment >= 0);
1422 : :
1423 [ + + ]: 7457 : if (!config->use_environment) {
1424 : 1924 : *dest = NULL;
1425 : 1924 : return _PyStatus_OK();
1426 : : }
1427 : :
1428 : : #ifdef MS_WINDOWS
1429 : : const wchar_t *var = _wgetenv(wname);
1430 : : if (!var || var[0] == '\0') {
1431 : : *dest = NULL;
1432 : : return _PyStatus_OK();
1433 : : }
1434 : :
1435 : : return PyConfig_SetString(config, dest, var);
1436 : : #else
1437 : 5533 : const char *var = getenv(name);
1438 [ + + + + ]: 5533 : if (!var || var[0] == '\0') {
1439 : 5463 : *dest = NULL;
1440 : 5463 : return _PyStatus_OK();
1441 : : }
1442 : :
1443 : 70 : return config_set_bytes_string(config, dest, var, decode_err_msg);
1444 : : #endif
1445 : : }
1446 : :
1447 : :
1448 : : #define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
1449 : : config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
1450 : :
1451 : :
1452 : : static void
1453 : 3053 : config_get_global_vars(PyConfig *config)
1454 : : {
1455 : : _Py_COMP_DIAG_PUSH
1456 : : _Py_COMP_DIAG_IGNORE_DEPR_DECLS
1457 [ + + ]: 3053 : if (config->_config_init != _PyConfig_INIT_COMPAT) {
1458 : : /* Python and Isolated configuration ignore global variables */
1459 : 2994 : return;
1460 : : }
1461 : :
1462 : : #define COPY_FLAG(ATTR, VALUE) \
1463 : : if (config->ATTR == -1) { \
1464 : : config->ATTR = VALUE; \
1465 : : }
1466 : : #define COPY_NOT_FLAG(ATTR, VALUE) \
1467 : : if (config->ATTR == -1) { \
1468 : : config->ATTR = !(VALUE); \
1469 : : }
1470 : :
1471 [ + + ]: 59 : COPY_FLAG(isolated, Py_IsolatedFlag);
1472 [ + - ]: 59 : COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
1473 [ + + ]: 59 : COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1474 [ + + ]: 59 : COPY_FLAG(inspect, Py_InspectFlag);
1475 [ + + ]: 59 : COPY_FLAG(interactive, Py_InteractiveFlag);
1476 [ + + ]: 59 : COPY_FLAG(optimization_level, Py_OptimizeFlag);
1477 [ + - ]: 59 : COPY_FLAG(parser_debug, Py_DebugFlag);
1478 [ + + ]: 59 : COPY_FLAG(verbose, Py_VerboseFlag);
1479 [ + + ]: 59 : COPY_FLAG(quiet, Py_QuietFlag);
1480 : : #ifdef MS_WINDOWS
1481 : : COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1482 : : #endif
1483 [ + + ]: 59 : COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
1484 : :
1485 [ + + ]: 59 : COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1486 [ + + ]: 59 : COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1487 [ + + ]: 59 : COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1488 [ + + ]: 59 : COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1489 : :
1490 : : #undef COPY_FLAG
1491 : : #undef COPY_NOT_FLAG
1492 : : _Py_COMP_DIAG_POP
1493 : : }
1494 : :
1495 : :
1496 : : /* Set Py_xxx global configuration variables from 'config' configuration. */
1497 : : static void
1498 : 3011 : config_set_global_vars(const PyConfig *config)
1499 : : {
1500 : : _Py_COMP_DIAG_PUSH
1501 : : _Py_COMP_DIAG_IGNORE_DEPR_DECLS
1502 : : #define COPY_FLAG(ATTR, VAR) \
1503 : : if (config->ATTR != -1) { \
1504 : : VAR = config->ATTR; \
1505 : : }
1506 : : #define COPY_NOT_FLAG(ATTR, VAR) \
1507 : : if (config->ATTR != -1) { \
1508 : : VAR = !config->ATTR; \
1509 : : }
1510 : :
1511 [ + - ]: 3011 : COPY_FLAG(isolated, Py_IsolatedFlag);
1512 [ + - ]: 3011 : COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
1513 [ + - ]: 3011 : COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1514 [ + - ]: 3011 : COPY_FLAG(inspect, Py_InspectFlag);
1515 [ + - ]: 3011 : COPY_FLAG(interactive, Py_InteractiveFlag);
1516 [ + - ]: 3011 : COPY_FLAG(optimization_level, Py_OptimizeFlag);
1517 [ + - ]: 3011 : COPY_FLAG(parser_debug, Py_DebugFlag);
1518 [ + - ]: 3011 : COPY_FLAG(verbose, Py_VerboseFlag);
1519 [ + - ]: 3011 : COPY_FLAG(quiet, Py_QuietFlag);
1520 : : #ifdef MS_WINDOWS
1521 : : COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1522 : : #endif
1523 [ + - ]: 3011 : COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
1524 : :
1525 [ + - ]: 3011 : COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1526 [ + - ]: 3011 : COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1527 [ + - ]: 3011 : COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1528 [ + - ]: 3011 : COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1529 : :
1530 : : /* Random or non-zero hash seed */
1531 [ + + ]: 3038 : Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1532 [ + + ]: 27 : config->hash_seed != 0);
1533 : :
1534 : : #undef COPY_FLAG
1535 : : #undef COPY_NOT_FLAG
1536 : : _Py_COMP_DIAG_POP
1537 : 3011 : }
1538 : :
1539 : :
1540 : : static const wchar_t*
1541 : 24168 : config_get_xoption(const PyConfig *config, wchar_t *name)
1542 : : {
1543 : 24168 : return _Py_get_xoption(&config->xoptions, name);
1544 : : }
1545 : :
1546 : : static const wchar_t*
1547 : 6163 : config_get_xoption_value(const PyConfig *config, wchar_t *name)
1548 : : {
1549 : 6163 : const wchar_t *xoption = config_get_xoption(config, name);
1550 [ + + ]: 6163 : if (xoption == NULL) {
1551 : 6147 : return NULL;
1552 : : }
1553 : 16 : const wchar_t *sep = wcschr(xoption, L'=');
1554 [ + + ]: 16 : return sep ? sep + 1 : L"";
1555 : : }
1556 : :
1557 : :
1558 : : static PyStatus
1559 : 1103 : config_init_hash_seed(PyConfig *config)
1560 : : {
1561 : : static_assert(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc),
1562 : : "_Py_HashSecret_t has wrong size");
1563 : :
1564 : 1103 : const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
1565 : :
1566 : : /* Convert a text seed to a numeric one */
1567 [ + + + + ]: 1103 : if (seed_text && strcmp(seed_text, "random") != 0) {
1568 : 24 : const char *endptr = seed_text;
1569 : : unsigned long seed;
1570 : 24 : errno = 0;
1571 : 24 : seed = strtoul(seed_text, (char **)&endptr, 10);
1572 [ + - ]: 24 : if (*endptr != '\0'
1573 [ + - ]: 24 : || seed > MAX_HASH_SEED
1574 [ - + - - ]: 24 : || (errno == ERANGE && seed == ULONG_MAX))
1575 : : {
1576 : 0 : return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
1577 : : "or an integer in range [0; 4294967295]");
1578 : : }
1579 : : /* Use a specific hash */
1580 : 24 : config->use_hash_seed = 1;
1581 : 24 : config->hash_seed = seed;
1582 : : }
1583 : : else {
1584 : : /* Use a random hash */
1585 : 1079 : config->use_hash_seed = 0;
1586 : 1079 : config->hash_seed = 0;
1587 : : }
1588 : 1103 : return _PyStatus_OK();
1589 : : }
1590 : :
1591 : :
1592 : : static int
1593 : 6 : config_wstr_to_int(const wchar_t *wstr, int *result)
1594 : : {
1595 : 6 : const wchar_t *endptr = wstr;
1596 : 6 : errno = 0;
1597 : 6 : long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1598 [ + - - + ]: 6 : if (*endptr != '\0' || errno == ERANGE) {
1599 : 0 : return -1;
1600 : : }
1601 [ + - - + ]: 6 : if (value < INT_MIN || value > INT_MAX) {
1602 : 0 : return -1;
1603 : : }
1604 : :
1605 : 6 : *result = (int)value;
1606 : 6 : return 0;
1607 : : }
1608 : :
1609 : :
1610 : : static PyStatus
1611 : 1108 : config_read_env_vars(PyConfig *config)
1612 : : {
1613 : : PyStatus status;
1614 : 1108 : int use_env = config->use_environment;
1615 : :
1616 : : /* Get environment variables */
1617 : 1108 : _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1618 : 1108 : _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1619 : 1108 : _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1620 : 1108 : _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
1621 : :
1622 : 1108 : int dont_write_bytecode = 0;
1623 : 1108 : _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
1624 [ + + ]: 1108 : if (dont_write_bytecode) {
1625 : 5 : config->write_bytecode = 0;
1626 : : }
1627 : :
1628 : 1108 : int no_user_site_directory = 0;
1629 : 1108 : _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
1630 [ + + ]: 1108 : if (no_user_site_directory) {
1631 : 3 : config->user_site_directory = 0;
1632 : : }
1633 : :
1634 : 1108 : int unbuffered_stdio = 0;
1635 : 1108 : _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
1636 [ + + ]: 1108 : if (unbuffered_stdio) {
1637 : 3 : config->buffered_stdio = 0;
1638 : : }
1639 : :
1640 : : #ifdef MS_WINDOWS
1641 : : _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
1642 : : "PYTHONLEGACYWINDOWSSTDIO");
1643 : : #endif
1644 : :
1645 [ - + ]: 1108 : if (config_get_env(config, "PYTHONDUMPREFS")) {
1646 : 0 : config->dump_refs = 1;
1647 : : }
1648 [ + + ]: 1108 : if (config_get_env(config, "PYTHONMALLOCSTATS")) {
1649 : 3 : config->malloc_stats = 1;
1650 : : }
1651 : :
1652 [ + - ]: 1108 : if (config->dump_refs_file == NULL) {
1653 : 1108 : status = CONFIG_GET_ENV_DUP(config, &config->dump_refs_file,
1654 : : L"PYTHONDUMPREFSFILE", "PYTHONDUMPREFSFILE");
1655 [ - + ]: 1108 : if (_PyStatus_EXCEPTION(status)) {
1656 : 0 : return status;
1657 : : }
1658 : : }
1659 : :
1660 [ + - ]: 1108 : if (config->pythonpath_env == NULL) {
1661 : 1108 : status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1662 : : L"PYTHONPATH", "PYTHONPATH");
1663 [ - + ]: 1108 : if (_PyStatus_EXCEPTION(status)) {
1664 : 0 : return status;
1665 : : }
1666 : : }
1667 : :
1668 [ + + ]: 1108 : if(config->platlibdir == NULL) {
1669 : 1106 : status = CONFIG_GET_ENV_DUP(config, &config->platlibdir,
1670 : : L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR");
1671 [ - + ]: 1106 : if (_PyStatus_EXCEPTION(status)) {
1672 : 0 : return status;
1673 : : }
1674 : : }
1675 : :
1676 [ + + ]: 1108 : if (config->use_hash_seed < 0) {
1677 : 1103 : status = config_init_hash_seed(config);
1678 [ - + ]: 1103 : if (_PyStatus_EXCEPTION(status)) {
1679 : 0 : return status;
1680 : : }
1681 : : }
1682 : :
1683 [ + + ]: 1108 : if (config_get_env(config, "PYTHONSAFEPATH")) {
1684 : 2 : config->safe_path = 1;
1685 : : }
1686 : :
1687 : 1108 : return _PyStatus_OK();
1688 : : }
1689 : :
1690 : :
1691 : : static PyStatus
1692 : 2940 : config_init_tracemalloc(PyConfig *config)
1693 : : {
1694 : : int nframe;
1695 : : int valid;
1696 : :
1697 : 2940 : const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
1698 [ + + ]: 2940 : if (env) {
1699 [ + - ]: 7 : if (!_Py_str_to_int(env, &nframe)) {
1700 : 7 : valid = (nframe >= 0);
1701 : : }
1702 : : else {
1703 : 0 : valid = 0;
1704 : : }
1705 [ + + ]: 7 : if (!valid) {
1706 : 1 : return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
1707 : : }
1708 : 6 : config->tracemalloc = nframe;
1709 : : }
1710 : :
1711 : 2939 : const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1712 [ + + ]: 2939 : if (xoption) {
1713 : 9 : const wchar_t *sep = wcschr(xoption, L'=');
1714 [ + + ]: 9 : if (sep) {
1715 [ + - ]: 6 : if (!config_wstr_to_int(sep + 1, &nframe)) {
1716 : 6 : valid = (nframe >= 0);
1717 : : }
1718 : : else {
1719 : 0 : valid = 0;
1720 : : }
1721 [ + + ]: 6 : if (!valid) {
1722 : 1 : return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1723 : : "invalid number of frames");
1724 : : }
1725 : : }
1726 : : else {
1727 : : /* -X tracemalloc behaves as -X tracemalloc=1 */
1728 : 3 : nframe = 1;
1729 : : }
1730 : 8 : config->tracemalloc = nframe;
1731 : : }
1732 : 2938 : return _PyStatus_OK();
1733 : : }
1734 : :
1735 : :
1736 : : static PyStatus
1737 : 3031 : config_init_pycache_prefix(PyConfig *config)
1738 : : {
1739 : : assert(config->pycache_prefix == NULL);
1740 : :
1741 : 3031 : const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1742 [ + + ]: 3031 : if (xoption) {
1743 : 4 : const wchar_t *sep = wcschr(xoption, L'=');
1744 [ + + + + ]: 4 : if (sep && wcslen(sep) > 1) {
1745 : 2 : config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1746 [ - + ]: 2 : if (config->pycache_prefix == NULL) {
1747 : 0 : return _PyStatus_NO_MEMORY();
1748 : : }
1749 : : }
1750 : : else {
1751 : : // PYTHONPYCACHEPREFIX env var ignored
1752 : : // if "-X pycache_prefix=" option is used
1753 : 2 : config->pycache_prefix = NULL;
1754 : : }
1755 : 4 : return _PyStatus_OK();
1756 : : }
1757 : :
1758 : 3027 : return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1759 : : L"PYTHONPYCACHEPREFIX",
1760 : : "PYTHONPYCACHEPREFIX");
1761 : : }
1762 : :
1763 : :
1764 : : static PyStatus
1765 : 3035 : config_read_complex_options(PyConfig *config)
1766 : : {
1767 : : /* More complex options configured by env var and -X option */
1768 [ + + ]: 3035 : if (config->faulthandler < 0) {
1769 [ + + ]: 2940 : if (config_get_env(config, "PYTHONFAULTHANDLER")
1770 [ + + ]: 2937 : || config_get_xoption(config, L"faulthandler")) {
1771 : 1069 : config->faulthandler = 1;
1772 : : }
1773 : : }
1774 [ + + ]: 3035 : if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
1775 [ + + ]: 3032 : || config_get_xoption(config, L"importtime")) {
1776 : 4 : config->import_time = 1;
1777 : : }
1778 : :
1779 [ + + ]: 3035 : if (config_get_env(config, "PYTHONNODEBUGRANGES")
1780 [ + + ]: 3031 : || config_get_xoption(config, L"no_debug_ranges")) {
1781 : 9 : config->code_debug_ranges = 0;
1782 : : }
1783 : :
1784 : : PyStatus status;
1785 [ + + ]: 3035 : if (config->tracemalloc < 0) {
1786 : 2940 : status = config_init_tracemalloc(config);
1787 [ + + ]: 2940 : if (_PyStatus_EXCEPTION(status)) {
1788 : 2 : return status;
1789 : : }
1790 : : }
1791 : :
1792 [ + + ]: 3033 : if (config->pycache_prefix == NULL) {
1793 : 3031 : status = config_init_pycache_prefix(config);
1794 [ - + ]: 3031 : if (_PyStatus_EXCEPTION(status)) {
1795 : 0 : return status;
1796 : : }
1797 : : }
1798 : 3033 : return _PyStatus_OK();
1799 : : }
1800 : :
1801 : :
1802 : : static const wchar_t *
1803 : 2779 : config_get_stdio_errors(const PyPreConfig *preconfig)
1804 : : {
1805 [ + + ]: 2779 : if (preconfig->utf8_mode) {
1806 : : /* UTF-8 Mode uses UTF-8/surrogateescape */
1807 : 60 : return L"surrogateescape";
1808 : : }
1809 : :
1810 : : #ifndef MS_WINDOWS
1811 : 2719 : const char *loc = setlocale(LC_CTYPE, NULL);
1812 [ + - ]: 2719 : if (loc != NULL) {
1813 : : /* surrogateescape is the default in the legacy C and POSIX locales */
1814 [ + + - + ]: 2719 : if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
1815 : 65 : return L"surrogateescape";
1816 : : }
1817 : :
1818 : : #ifdef PY_COERCE_C_LOCALE
1819 : : /* surrogateescape is the default in locale coercion target locales */
1820 [ + + ]: 2654 : if (_Py_IsLocaleCoercionTarget(loc)) {
1821 : 46 : return L"surrogateescape";
1822 : : }
1823 : : #endif
1824 : : }
1825 : :
1826 : 2608 : return L"strict";
1827 : : #else
1828 : : /* On Windows, always use surrogateescape by default */
1829 : : return L"surrogateescape";
1830 : : #endif
1831 : : }
1832 : :
1833 : :
1834 : : // See also config_get_fs_encoding()
1835 : : static PyStatus
1836 : 5687 : config_get_locale_encoding(PyConfig *config, const PyPreConfig *preconfig,
1837 : : wchar_t **locale_encoding)
1838 : : {
1839 : : wchar_t *encoding;
1840 [ + + ]: 5687 : if (preconfig->utf8_mode) {
1841 : 61 : encoding = _PyMem_RawWcsdup(L"utf-8");
1842 : : }
1843 : : else {
1844 : 5626 : encoding = _Py_GetLocaleEncoding();
1845 : : }
1846 [ - + ]: 5687 : if (encoding == NULL) {
1847 : 0 : return _PyStatus_NO_MEMORY();
1848 : : }
1849 : 5687 : PyStatus status = PyConfig_SetString(config, locale_encoding, encoding);
1850 : 5687 : PyMem_RawFree(encoding);
1851 : 5687 : return status;
1852 : : }
1853 : :
1854 : :
1855 : : static PyStatus
1856 : 3033 : config_init_stdio_encoding(PyConfig *config,
1857 : : const PyPreConfig *preconfig)
1858 : : {
1859 : : PyStatus status;
1860 : :
1861 : : /* If Py_SetStandardStreamEncoding() has been called, use its
1862 : : arguments if they are not NULL. */
1863 [ + + + + ]: 3033 : if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
1864 : 2 : status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1865 : : _Py_StandardStreamEncoding,
1866 : : "_Py_StandardStreamEncoding");
1867 [ - + ]: 2 : if (_PyStatus_EXCEPTION(status)) {
1868 : 0 : return status;
1869 : : }
1870 : : }
1871 : :
1872 [ + + + + ]: 3033 : if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
1873 : 2 : status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1874 : : _Py_StandardStreamErrors,
1875 : : "_Py_StandardStreamErrors");
1876 [ - + ]: 2 : if (_PyStatus_EXCEPTION(status)) {
1877 : 0 : return status;
1878 : : }
1879 : : }
1880 : :
1881 : : // Exit if encoding and errors are defined
1882 [ + + + + ]: 3033 : if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
1883 : 67 : return _PyStatus_OK();
1884 : : }
1885 : :
1886 : : /* PYTHONIOENCODING environment variable */
1887 : 2966 : const char *opt = config_get_env(config, "PYTHONIOENCODING");
1888 [ + + ]: 2966 : if (opt) {
1889 : 189 : char *pythonioencoding = _PyMem_RawStrdup(opt);
1890 [ - + ]: 189 : if (pythonioencoding == NULL) {
1891 : 0 : return _PyStatus_NO_MEMORY();
1892 : : }
1893 : :
1894 : 189 : char *errors = strchr(pythonioencoding, ':');
1895 [ + + ]: 189 : if (errors) {
1896 : 18 : *errors = '\0';
1897 : 18 : errors++;
1898 [ + + ]: 18 : if (!errors[0]) {
1899 : 5 : errors = NULL;
1900 : : }
1901 : : }
1902 : :
1903 : : /* Does PYTHONIOENCODING contain an encoding? */
1904 [ + + ]: 189 : if (pythonioencoding[0]) {
1905 [ + + ]: 183 : if (config->stdio_encoding == NULL) {
1906 : 182 : status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1907 : : pythonioencoding,
1908 : : "PYTHONIOENCODING environment variable");
1909 [ - + ]: 182 : if (_PyStatus_EXCEPTION(status)) {
1910 : 0 : PyMem_RawFree(pythonioencoding);
1911 : 0 : return status;
1912 : : }
1913 : : }
1914 : :
1915 : : /* If the encoding is set but not the error handler,
1916 : : use "strict" error handler by default.
1917 : : PYTHONIOENCODING=latin1 behaves as
1918 : : PYTHONIOENCODING=latin1:strict. */
1919 [ + + ]: 183 : if (!errors) {
1920 : 174 : errors = "strict";
1921 : : }
1922 : : }
1923 : :
1924 [ + + + + ]: 189 : if (config->stdio_errors == NULL && errors != NULL) {
1925 : 186 : status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1926 : : errors,
1927 : : "PYTHONIOENCODING environment variable");
1928 [ - + ]: 186 : if (_PyStatus_EXCEPTION(status)) {
1929 : 0 : PyMem_RawFree(pythonioencoding);
1930 : 0 : return status;
1931 : : }
1932 : : }
1933 : :
1934 : 189 : PyMem_RawFree(pythonioencoding);
1935 : : }
1936 : :
1937 : : /* Choose the default error handler based on the current locale. */
1938 [ + + ]: 2966 : if (config->stdio_encoding == NULL) {
1939 : 2783 : status = config_get_locale_encoding(config, preconfig,
1940 : : &config->stdio_encoding);
1941 [ - + ]: 2783 : if (_PyStatus_EXCEPTION(status)) {
1942 : 0 : return status;
1943 : : }
1944 : : }
1945 [ + + ]: 2966 : if (config->stdio_errors == NULL) {
1946 : 2779 : const wchar_t *errors = config_get_stdio_errors(preconfig);
1947 : : assert(errors != NULL);
1948 : :
1949 : 2779 : status = PyConfig_SetString(config, &config->stdio_errors, errors);
1950 [ - + ]: 2779 : if (_PyStatus_EXCEPTION(status)) {
1951 : 0 : return status;
1952 : : }
1953 : : }
1954 : :
1955 : 2966 : return _PyStatus_OK();
1956 : : }
1957 : :
1958 : :
1959 : : // See also config_get_locale_encoding()
1960 : : static PyStatus
1961 : 2968 : config_get_fs_encoding(PyConfig *config, const PyPreConfig *preconfig,
1962 : : wchar_t **fs_encoding)
1963 : : {
1964 : : #ifdef _Py_FORCE_UTF8_FS_ENCODING
1965 : : return PyConfig_SetString(config, fs_encoding, L"utf-8");
1966 : : #elif defined(MS_WINDOWS)
1967 : : const wchar_t *encoding;
1968 : : if (preconfig->legacy_windows_fs_encoding) {
1969 : : // Legacy Windows filesystem encoding: mbcs/replace
1970 : : encoding = L"mbcs";
1971 : : }
1972 : : else {
1973 : : // Windows defaults to utf-8/surrogatepass (PEP 529)
1974 : : encoding = L"utf-8";
1975 : : }
1976 : : return PyConfig_SetString(config, fs_encoding, encoding);
1977 : : #else // !MS_WINDOWS
1978 [ + + ]: 2968 : if (preconfig->utf8_mode) {
1979 : 64 : return PyConfig_SetString(config, fs_encoding, L"utf-8");
1980 : : }
1981 : :
1982 [ - + ]: 2904 : if (_Py_GetForceASCII()) {
1983 : 0 : return PyConfig_SetString(config, fs_encoding, L"ascii");
1984 : : }
1985 : :
1986 : 2904 : return config_get_locale_encoding(config, preconfig, fs_encoding);
1987 : : #endif // !MS_WINDOWS
1988 : : }
1989 : :
1990 : :
1991 : : static PyStatus
1992 : 2968 : config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
1993 : : {
1994 : : PyStatus status;
1995 : :
1996 [ + - ]: 2968 : if (config->filesystem_encoding == NULL) {
1997 : 2968 : status = config_get_fs_encoding(config, preconfig,
1998 : : &config->filesystem_encoding);
1999 [ - + ]: 2968 : if (_PyStatus_EXCEPTION(status)) {
2000 : 0 : return status;
2001 : : }
2002 : : }
2003 : :
2004 [ + - ]: 2968 : if (config->filesystem_errors == NULL) {
2005 : : const wchar_t *errors;
2006 : : #ifdef MS_WINDOWS
2007 : : if (preconfig->legacy_windows_fs_encoding) {
2008 : : errors = L"replace";
2009 : : }
2010 : : else {
2011 : : errors = L"surrogatepass";
2012 : : }
2013 : : #else
2014 : 2968 : errors = L"surrogateescape";
2015 : : #endif
2016 : 2968 : status = PyConfig_SetString(config, &config->filesystem_errors, errors);
2017 [ - + ]: 2968 : if (_PyStatus_EXCEPTION(status)) {
2018 : 0 : return status;
2019 : : }
2020 : : }
2021 : 2968 : return _PyStatus_OK();
2022 : : }
2023 : :
2024 : :
2025 : : static PyStatus
2026 : 6163 : config_init_import(PyConfig *config, int compute_path_config)
2027 : : {
2028 : : PyStatus status;
2029 : :
2030 : 6163 : status = _PyConfig_InitPathConfig(config, compute_path_config);
2031 [ - + ]: 6163 : if (_PyStatus_EXCEPTION(status)) {
2032 : 0 : return status;
2033 : : }
2034 : :
2035 : : /* -X frozen_modules=[on|off] */
2036 : 6163 : const wchar_t *value = config_get_xoption_value(config, L"frozen_modules");
2037 [ + + ]: 6163 : if (value == NULL) {
2038 : : }
2039 [ + + ]: 16 : else if (wcscmp(value, L"on") == 0) {
2040 : 4 : config->use_frozen_modules = 1;
2041 : : }
2042 [ + + ]: 12 : else if (wcscmp(value, L"off") == 0) {
2043 : 4 : config->use_frozen_modules = 0;
2044 : : }
2045 [ + - ]: 8 : else if (wcslen(value) == 0) {
2046 : : // "-X frozen_modules" and "-X frozen_modules=" both imply "on".
2047 : 8 : config->use_frozen_modules = 1;
2048 : : }
2049 : : else {
2050 : 0 : return PyStatus_Error("bad value for option -X frozen_modules "
2051 : : "(expected \"on\" or \"off\")");
2052 : : }
2053 : :
2054 : : assert(config->use_frozen_modules >= 0);
2055 : 6163 : return _PyStatus_OK();
2056 : : }
2057 : :
2058 : : PyStatus
2059 : 3134 : _PyConfig_InitImportConfig(PyConfig *config)
2060 : : {
2061 : 3134 : return config_init_import(config, 1);
2062 : : }
2063 : :
2064 : : // List of known xoptions to validate against the provided ones. Note that all
2065 : : // options are listed, even if they are only available if a specific macro is
2066 : : // set, like -X showrefcount which requires a debug build. In this case unknown
2067 : : // options are silently ignored.
2068 : : const wchar_t* known_xoptions[] = {
2069 : : L"faulthandler",
2070 : : L"showrefcount",
2071 : : L"tracemalloc",
2072 : : L"importtime",
2073 : : L"dev",
2074 : : L"utf8",
2075 : : L"pycache_prefix",
2076 : : L"warn_default_encoding",
2077 : : L"no_debug_ranges",
2078 : : L"frozen_modules",
2079 : : NULL,
2080 : : };
2081 : :
2082 : : static const wchar_t*
2083 : 3036 : _Py_check_xoptions(const PyWideStringList *xoptions, const wchar_t **names)
2084 : : {
2085 [ + + ]: 4350 : for (Py_ssize_t i=0; i < xoptions->length; i++) {
2086 : 1315 : const wchar_t *option = xoptions->items[i];
2087 : : size_t len;
2088 : 1315 : wchar_t *sep = wcschr(option, L'=');
2089 [ + + ]: 1315 : if (sep != NULL) {
2090 : 115 : len = (sep - option);
2091 : : }
2092 : : else {
2093 : 1200 : len = wcslen(option);
2094 : : }
2095 : 1315 : int found = 0;
2096 [ + + ]: 14465 : for (const wchar_t** name = names; *name != NULL; name++) {
2097 [ + + + - ]: 13150 : if (wcsncmp(option, *name, len) == 0 && (*name)[len] == L'\0') {
2098 : 1314 : found = 1;
2099 : : }
2100 : : }
2101 [ + + ]: 1315 : if (found == 0) {
2102 : 1 : return option;
2103 : : }
2104 : : }
2105 : 3035 : return NULL;
2106 : : }
2107 : :
2108 : : static PyStatus
2109 : 3036 : config_read(PyConfig *config, int compute_path_config)
2110 : : {
2111 : : PyStatus status;
2112 : 3036 : const PyPreConfig *preconfig = &_PyRuntime.preconfig;
2113 : :
2114 [ + + ]: 3036 : if (config->use_environment) {
2115 : 1108 : status = config_read_env_vars(config);
2116 [ - + ]: 1108 : if (_PyStatus_EXCEPTION(status)) {
2117 : 0 : return status;
2118 : : }
2119 : : }
2120 : :
2121 : : /* -X options */
2122 : 3036 : const wchar_t* option = _Py_check_xoptions(&config->xoptions, known_xoptions);
2123 [ + + ]: 3036 : if (option != NULL) {
2124 : 1 : return PyStatus_Error("Unknown value for option -X (see --help-xoptions)");
2125 : : }
2126 : :
2127 [ + + ]: 3035 : if (config_get_xoption(config, L"showrefcount")) {
2128 : 6 : config->show_ref_count = 1;
2129 : : }
2130 : :
2131 : 3035 : status = config_read_complex_options(config);
2132 [ + + ]: 3035 : if (_PyStatus_EXCEPTION(status)) {
2133 : 2 : return status;
2134 : : }
2135 : :
2136 [ + + ]: 3033 : if (config->_install_importlib) {
2137 : 3029 : status = config_init_import(config, compute_path_config);
2138 [ - + ]: 3029 : if (_PyStatus_EXCEPTION(status)) {
2139 : 0 : return status;
2140 : : }
2141 : : }
2142 : :
2143 : : /* default values */
2144 [ + + ]: 3033 : if (config->dev_mode) {
2145 [ + + ]: 36 : if (config->faulthandler < 0) {
2146 : 26 : config->faulthandler = 1;
2147 : : }
2148 : : }
2149 [ + + ]: 3033 : if (config->faulthandler < 0) {
2150 : 1845 : config->faulthandler = 0;
2151 : : }
2152 [ + + ]: 3033 : if (config->tracemalloc < 0) {
2153 : 2924 : config->tracemalloc = 0;
2154 : : }
2155 [ + + ]: 3033 : if (config->use_hash_seed < 0) {
2156 : 1834 : config->use_hash_seed = 0;
2157 : 1834 : config->hash_seed = 0;
2158 : : }
2159 : :
2160 [ + + - + ]: 3033 : if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
2161 : 2968 : status = config_init_fs_encoding(config, preconfig);
2162 [ - + ]: 2968 : if (_PyStatus_EXCEPTION(status)) {
2163 : 0 : return status;
2164 : : }
2165 : : }
2166 : :
2167 : 3033 : status = config_init_stdio_encoding(config, preconfig);
2168 [ - + ]: 3033 : if (_PyStatus_EXCEPTION(status)) {
2169 : 0 : return status;
2170 : : }
2171 : :
2172 [ + + ]: 3033 : if (config->argv.length < 1) {
2173 : : /* Ensure at least one (empty) argument is seen */
2174 : 66 : status = PyWideStringList_Append(&config->argv, L"");
2175 [ - + ]: 66 : if (_PyStatus_EXCEPTION(status)) {
2176 : 0 : return status;
2177 : : }
2178 : : }
2179 : :
2180 [ + + ]: 3033 : if (config->check_hash_pycs_mode == NULL) {
2181 : 2964 : status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
2182 : : L"default");
2183 [ - + ]: 2964 : if (_PyStatus_EXCEPTION(status)) {
2184 : 0 : return status;
2185 : : }
2186 : : }
2187 : :
2188 [ - + ]: 3033 : if (config->configure_c_stdio < 0) {
2189 : 0 : config->configure_c_stdio = 1;
2190 : : }
2191 : :
2192 : : // Only parse arguments once.
2193 [ + + ]: 3033 : if (config->parse_argv == 1) {
2194 : 2900 : config->parse_argv = 2;
2195 : : }
2196 : :
2197 : 3033 : return _PyStatus_OK();
2198 : : }
2199 : :
2200 : :
2201 : : static void
2202 : 2923 : config_init_stdio(const PyConfig *config)
2203 : : {
2204 : : #if defined(MS_WINDOWS) || defined(__CYGWIN__)
2205 : : /* don't translate newlines (\r\n <=> \n) */
2206 : : _setmode(fileno(stdin), O_BINARY);
2207 : : _setmode(fileno(stdout), O_BINARY);
2208 : : _setmode(fileno(stderr), O_BINARY);
2209 : : #endif
2210 : :
2211 [ + + ]: 2923 : if (!config->buffered_stdio) {
2212 : : #ifdef HAVE_SETVBUF
2213 : 498 : setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
2214 : 498 : setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
2215 : 498 : setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
2216 : : #else /* !HAVE_SETVBUF */
2217 : : setbuf(stdin, (char *)NULL);
2218 : : setbuf(stdout, (char *)NULL);
2219 : : setbuf(stderr, (char *)NULL);
2220 : : #endif /* !HAVE_SETVBUF */
2221 : : }
2222 [ + + ]: 2425 : else if (config->interactive) {
2223 : : #ifdef MS_WINDOWS
2224 : : /* Doesn't have to have line-buffered -- use unbuffered */
2225 : : /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
2226 : : setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
2227 : : #else /* !MS_WINDOWS */
2228 : : #ifdef HAVE_SETVBUF
2229 : 16 : setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
2230 : 16 : setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
2231 : : #endif /* HAVE_SETVBUF */
2232 : : #endif /* !MS_WINDOWS */
2233 : : /* Leave stderr alone - it should be unbuffered anyway. */
2234 : : }
2235 : 2923 : }
2236 : :
2237 : :
2238 : : /* Write the configuration:
2239 : :
2240 : : - set Py_xxx global configuration variables
2241 : : - initialize C standard streams (stdin, stdout, stderr) */
2242 : : PyStatus
2243 : 3011 : _PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
2244 : : {
2245 : 3011 : config_set_global_vars(config);
2246 : :
2247 [ + + ]: 3011 : if (config->configure_c_stdio) {
2248 : 2923 : config_init_stdio(config);
2249 : : }
2250 : :
2251 : : /* Write the new pre-configuration into _PyRuntime */
2252 : 3011 : PyPreConfig *preconfig = &runtime->preconfig;
2253 : 3011 : preconfig->isolated = config->isolated;
2254 : 3011 : preconfig->use_environment = config->use_environment;
2255 : 3011 : preconfig->dev_mode = config->dev_mode;
2256 : :
2257 [ - + ]: 3011 : if (_Py_SetArgcArgv(config->orig_argv.length,
2258 : 3011 : config->orig_argv.items) < 0)
2259 : : {
2260 : 0 : return _PyStatus_NO_MEMORY();
2261 : : }
2262 : 3011 : return _PyStatus_OK();
2263 : : }
2264 : :
2265 : :
2266 : : /* --- PyConfig command line parser -------------------------- */
2267 : :
2268 : : static void
2269 : 12 : config_usage(int error, const wchar_t* program)
2270 : : {
2271 [ + + ]: 12 : FILE *f = error ? stderr : stdout;
2272 : :
2273 : 12 : fprintf(f, usage_line, program);
2274 [ + + ]: 12 : if (error)
2275 : 6 : fprintf(f, "Try `python -h' for more information.\n");
2276 : : else {
2277 : 6 : fputs(usage_help, f);
2278 : : }
2279 : 12 : }
2280 : :
2281 : : static void
2282 : 2 : config_envvars_usage()
2283 : : {
2284 : 2 : printf(usage_envvars, (wint_t)DELIM, (wint_t)DELIM, PYTHONHOMEHELP);
2285 : 2 : }
2286 : :
2287 : : static void
2288 : 2 : config_xoptions_usage()
2289 : : {
2290 : 2 : puts(usage_xoptions);
2291 : 2 : }
2292 : :
2293 : : static void
2294 : 1 : config_complete_usage(const wchar_t* program)
2295 : : {
2296 : 1 : config_usage(0, program);
2297 : 1 : puts("\n");
2298 : 1 : config_envvars_usage();
2299 : 1 : puts("\n");
2300 : 1 : config_xoptions_usage();
2301 : 1 : }
2302 : :
2303 : :
2304 : : /* Parse the command line arguments */
2305 : : static PyStatus
2306 : 2920 : config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
2307 : : Py_ssize_t *opt_index)
2308 : : {
2309 : : PyStatus status;
2310 : 2920 : const PyWideStringList *argv = &config->argv;
2311 : 2920 : int print_version = 0;
2312 : 2920 : const wchar_t* program = config->program_name;
2313 [ + + + - ]: 2920 : if (!program && argv->length >= 1) {
2314 : 2897 : program = argv->items[0];
2315 : : }
2316 : :
2317 : 2920 : _PyOS_ResetGetOpt();
2318 : 6690 : do {
2319 : 9610 : int longindex = -1;
2320 : 9610 : int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
2321 [ + + ]: 9610 : if (c == EOF) {
2322 : 406 : break;
2323 : : }
2324 : :
2325 [ + + ]: 9204 : if (c == 'c') {
2326 [ + - ]: 1627 : if (config->run_command == NULL) {
2327 : : /* -c is the last option; following arguments
2328 : : that look like options are left for the
2329 : : command to interpret. */
2330 : 1627 : size_t len = wcslen(_PyOS_optarg) + 1 + 1;
2331 : 1627 : wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
2332 [ - + ]: 1627 : if (command == NULL) {
2333 : 0 : return _PyStatus_NO_MEMORY();
2334 : : }
2335 : 1627 : memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
2336 : 1627 : command[len - 2] = '\n';
2337 : 1627 : command[len - 1] = 0;
2338 : 1627 : config->run_command = command;
2339 : : }
2340 : 1627 : break;
2341 : : }
2342 : :
2343 [ + + ]: 7577 : if (c == 'm') {
2344 : : /* -m is the last option; following arguments
2345 : : that look like options are left for the
2346 : : module to interpret. */
2347 [ + - ]: 873 : if (config->run_module == NULL) {
2348 : 873 : config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
2349 [ - + ]: 873 : if (config->run_module == NULL) {
2350 : 0 : return _PyStatus_NO_MEMORY();
2351 : : }
2352 : : }
2353 : 873 : break;
2354 : : }
2355 : :
2356 [ + + + + : 6704 : switch (c) {
+ - + + +
+ + + + -
+ + - + +
+ + + + ]
2357 : : // Integers represent long options, see Python/getopt.c
2358 : 3 : case 0:
2359 : : // check-hash-based-pycs
2360 [ + + ]: 3 : if (wcscmp(_PyOS_optarg, L"always") == 0
2361 [ + + ]: 2 : || wcscmp(_PyOS_optarg, L"never") == 0
2362 [ + - ]: 1 : || wcscmp(_PyOS_optarg, L"default") == 0)
2363 : : {
2364 : 3 : status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
2365 : : _PyOS_optarg);
2366 [ - + ]: 3 : if (_PyStatus_EXCEPTION(status)) {
2367 : 14 : return status;
2368 : : }
2369 : : } else {
2370 : 0 : fprintf(stderr, "--check-hash-based-pycs must be one of "
2371 : : "'default', 'always', or 'never'\n");
2372 : 0 : config_usage(1, program);
2373 : 0 : return _PyStatus_EXIT(2);
2374 : : }
2375 : 6690 : break;
2376 : :
2377 : 1 : case 1:
2378 : : // help-all
2379 : 1 : config_complete_usage(program);
2380 : 1 : return _PyStatus_EXIT(0);
2381 : :
2382 : 1 : case 2:
2383 : : // help-env
2384 : 1 : config_envvars_usage();
2385 : 1 : return _PyStatus_EXIT(0);
2386 : :
2387 : 1 : case 3:
2388 : : // help-xoptions
2389 : 1 : config_xoptions_usage();
2390 : 1 : return _PyStatus_EXIT(0);
2391 : :
2392 : 1874 : case 'b':
2393 : 1874 : config->bytes_warning++;
2394 : 1874 : break;
2395 : :
2396 : 0 : case 'd':
2397 : 0 : config->parser_debug++;
2398 : 0 : break;
2399 : :
2400 : 12 : case 'i':
2401 : 12 : config->inspect++;
2402 : 12 : config->interactive++;
2403 : 12 : break;
2404 : :
2405 : 3148 : case 'E':
2406 : : case 'I':
2407 : : case 'X':
2408 : : /* option handled by _PyPreCmdline_Read() */
2409 : 3148 : break;
2410 : :
2411 : : /* case 'J': reserved for Jython */
2412 : :
2413 : 24 : case 'O':
2414 : 24 : config->optimization_level++;
2415 : 24 : break;
2416 : :
2417 : 4 : case 'P':
2418 : 4 : config->safe_path = 1;
2419 : 4 : break;
2420 : :
2421 : 9 : case 'B':
2422 : 9 : config->write_bytecode = 0;
2423 : 9 : break;
2424 : :
2425 : 8 : case 's':
2426 : 8 : config->user_site_directory = 0;
2427 : 8 : break;
2428 : :
2429 : 117 : case 'S':
2430 : 117 : config->site_import = 0;
2431 : 117 : break;
2432 : :
2433 : 0 : case 't':
2434 : : /* ignored for backwards compatibility */
2435 : 0 : break;
2436 : :
2437 : 495 : case 'u':
2438 : 495 : config->buffered_stdio = 0;
2439 : 495 : break;
2440 : :
2441 : 8 : case 'v':
2442 : 8 : config->verbose++;
2443 : 8 : break;
2444 : :
2445 : 0 : case 'x':
2446 : 0 : config->skip_source_first_line = 1;
2447 : 0 : break;
2448 : :
2449 : 5 : case 'h':
2450 : : case '?':
2451 : 5 : config_usage(0, program);
2452 : 5 : return _PyStatus_EXIT(0);
2453 : :
2454 : 4 : case 'V':
2455 : 4 : print_version++;
2456 : 4 : break;
2457 : :
2458 : 981 : case 'W':
2459 : 981 : status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2460 [ - + ]: 981 : if (_PyStatus_EXCEPTION(status)) {
2461 : 0 : return status;
2462 : : }
2463 : 981 : break;
2464 : :
2465 : 1 : case 'q':
2466 : 1 : config->quiet++;
2467 : 1 : break;
2468 : :
2469 : 2 : case 'R':
2470 : 2 : config->use_hash_seed = 0;
2471 : 2 : break;
2472 : :
2473 : : /* This space reserved for other options */
2474 : :
2475 : 6 : default:
2476 : : /* unknown argument: parsing failed */
2477 : 6 : config_usage(1, program);
2478 : 6 : return _PyStatus_EXIT(2);
2479 : : }
2480 : : } while (1);
2481 : :
2482 [ + + ]: 2906 : if (print_version) {
2483 [ + + ]: 4 : printf("Python %s\n",
2484 : 1 : (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
2485 : 3 : return _PyStatus_EXIT(0);
2486 : : }
2487 : :
2488 [ + + + + ]: 2903 : if (config->run_command == NULL && config->run_module == NULL
2489 [ + + ]: 403 : && _PyOS_optind < argv->length
2490 [ + + ]: 371 : && wcscmp(argv->items[_PyOS_optind], L"-") != 0
2491 [ + - ]: 367 : && config->run_filename == NULL)
2492 : : {
2493 : 367 : config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
2494 [ - + ]: 367 : if (config->run_filename == NULL) {
2495 : 0 : return _PyStatus_NO_MEMORY();
2496 : : }
2497 : : }
2498 : :
2499 [ + + + + ]: 2903 : if (config->run_command != NULL || config->run_module != NULL) {
2500 : : /* Backup _PyOS_optind */
2501 : 2500 : _PyOS_optind--;
2502 : : }
2503 : :
2504 : 2903 : *opt_index = _PyOS_optind;
2505 : :
2506 : 2903 : return _PyStatus_OK();
2507 : : }
2508 : :
2509 : :
2510 : : #ifdef MS_WINDOWS
2511 : : # define WCSTOK wcstok_s
2512 : : #else
2513 : : # define WCSTOK wcstok
2514 : : #endif
2515 : :
2516 : : /* Get warning options from PYTHONWARNINGS environment variable. */
2517 : : static PyStatus
2518 : 1108 : config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
2519 : : {
2520 : : PyStatus status;
2521 : : /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2522 : 1108 : wchar_t *env = NULL;
2523 : 1108 : status = CONFIG_GET_ENV_DUP(config, &env,
2524 : : L"PYTHONWARNINGS", "PYTHONWARNINGS");
2525 [ - + ]: 1108 : if (_PyStatus_EXCEPTION(status)) {
2526 : 0 : return status;
2527 : : }
2528 : :
2529 : : /* env var is not set or is empty */
2530 [ + + ]: 1108 : if (env == NULL) {
2531 : 1092 : return _PyStatus_OK();
2532 : : }
2533 : :
2534 : :
2535 : 16 : wchar_t *warning, *context = NULL;
2536 : 16 : for (warning = WCSTOK(env, L",", &context);
2537 [ + + ]: 36 : warning != NULL;
2538 : 20 : warning = WCSTOK(NULL, L",", &context))
2539 : : {
2540 : 20 : status = PyWideStringList_Append(warnoptions, warning);
2541 [ - + ]: 20 : if (_PyStatus_EXCEPTION(status)) {
2542 : 0 : PyMem_RawFree(env);
2543 : 0 : return status;
2544 : : }
2545 : : }
2546 : 16 : PyMem_RawFree(env);
2547 : 16 : return _PyStatus_OK();
2548 : : }
2549 : :
2550 : :
2551 : : static PyStatus
2552 : 1987 : warnoptions_append(PyConfig *config, PyWideStringList *options,
2553 : : const wchar_t *option)
2554 : : {
2555 : : /* config_init_warnoptions() add existing config warnoptions at the end:
2556 : : ensure that the new option is not already present in this list to
2557 : : prevent change the options order when config_init_warnoptions() is
2558 : : called twice. */
2559 [ + + ]: 1987 : if (_PyWideStringList_Find(&config->warnoptions, option)) {
2560 : : /* Already present: do nothing */
2561 : 4 : return _PyStatus_OK();
2562 : : }
2563 [ - + ]: 1983 : if (_PyWideStringList_Find(options, option)) {
2564 : : /* Already present: do nothing */
2565 : 0 : return _PyStatus_OK();
2566 : : }
2567 : 1983 : return PyWideStringList_Append(options, option);
2568 : : }
2569 : :
2570 : :
2571 : : static PyStatus
2572 : 9108 : warnoptions_extend(PyConfig *config, PyWideStringList *options,
2573 : : const PyWideStringList *options2)
2574 : : {
2575 : 9108 : const Py_ssize_t len = options2->length;
2576 : 9108 : wchar_t *const *items = options2->items;
2577 : :
2578 [ + + ]: 10115 : for (Py_ssize_t i = 0; i < len; i++) {
2579 : 1007 : PyStatus status = warnoptions_append(config, options, items[i]);
2580 [ - + ]: 1007 : if (_PyStatus_EXCEPTION(status)) {
2581 : 0 : return status;
2582 : : }
2583 : : }
2584 : 9108 : return _PyStatus_OK();
2585 : : }
2586 : :
2587 : :
2588 : : static PyStatus
2589 : 3036 : config_init_warnoptions(PyConfig *config,
2590 : : const PyWideStringList *cmdline_warnoptions,
2591 : : const PyWideStringList *env_warnoptions,
2592 : : const PyWideStringList *sys_warnoptions)
2593 : : {
2594 : : PyStatus status;
2595 : 3036 : PyWideStringList options = _PyWideStringList_INIT;
2596 : :
2597 : : /* Priority of warnings options, lowest to highest:
2598 : : *
2599 : : * - any implicit filters added by _warnings.c/warnings.py
2600 : : * - PyConfig.dev_mode: "default" filter
2601 : : * - PYTHONWARNINGS environment variable
2602 : : * - '-W' command line options
2603 : : * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2604 : : * "default::BytesWarning" or "error::BytesWarning" filter
2605 : : * - early PySys_AddWarnOption() calls
2606 : : * - PyConfig.warnoptions
2607 : : *
2608 : : * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2609 : : * module works on the basis of "the most recently added filter will be
2610 : : * checked first", we add the lowest precedence entries first so that later
2611 : : * entries override them.
2612 : : */
2613 : :
2614 [ + + ]: 3036 : if (config->dev_mode) {
2615 : 36 : status = warnoptions_append(config, &options, L"default");
2616 [ - + ]: 36 : if (_PyStatus_EXCEPTION(status)) {
2617 : 0 : goto error;
2618 : : }
2619 : : }
2620 : :
2621 : 3036 : status = warnoptions_extend(config, &options, env_warnoptions);
2622 [ - + ]: 3036 : if (_PyStatus_EXCEPTION(status)) {
2623 : 0 : goto error;
2624 : : }
2625 : :
2626 : 3036 : status = warnoptions_extend(config, &options, cmdline_warnoptions);
2627 [ - + ]: 3036 : if (_PyStatus_EXCEPTION(status)) {
2628 : 0 : goto error;
2629 : : }
2630 : :
2631 : : /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2632 : : * don't even try to emit a warning, so we skip setting the filter in that
2633 : : * case.
2634 : : */
2635 [ + + ]: 3036 : if (config->bytes_warning) {
2636 : : const wchar_t *filter;
2637 [ + + ]: 944 : if (config->bytes_warning> 1) {
2638 : 938 : filter = L"error::BytesWarning";
2639 : : }
2640 : : else {
2641 : 6 : filter = L"default::BytesWarning";
2642 : : }
2643 : 944 : status = warnoptions_append(config, &options, filter);
2644 [ - + ]: 944 : if (_PyStatus_EXCEPTION(status)) {
2645 : 0 : goto error;
2646 : : }
2647 : : }
2648 : :
2649 : 3036 : status = warnoptions_extend(config, &options, sys_warnoptions);
2650 [ - + ]: 3036 : if (_PyStatus_EXCEPTION(status)) {
2651 : 0 : goto error;
2652 : : }
2653 : :
2654 : : /* Always add all PyConfig.warnoptions options */
2655 : 3036 : status = _PyWideStringList_Extend(&options, &config->warnoptions);
2656 [ - + ]: 3036 : if (_PyStatus_EXCEPTION(status)) {
2657 : 0 : goto error;
2658 : : }
2659 : :
2660 : 3036 : _PyWideStringList_Clear(&config->warnoptions);
2661 : 3036 : config->warnoptions = options;
2662 : 3036 : return _PyStatus_OK();
2663 : :
2664 : 0 : error:
2665 : 0 : _PyWideStringList_Clear(&options);
2666 : 0 : return status;
2667 : : }
2668 : :
2669 : :
2670 : : static PyStatus
2671 : 2903 : config_update_argv(PyConfig *config, Py_ssize_t opt_index)
2672 : : {
2673 : 2903 : const PyWideStringList *cmdline_argv = &config->argv;
2674 : 2903 : PyWideStringList config_argv = _PyWideStringList_INIT;
2675 : :
2676 : : /* Copy argv to be able to modify it (to force -c/-m) */
2677 [ + + ]: 2903 : if (cmdline_argv->length <= opt_index) {
2678 : : /* Ensure at least one (empty) argument is seen */
2679 : 32 : PyStatus status = PyWideStringList_Append(&config_argv, L"");
2680 [ - + ]: 32 : if (_PyStatus_EXCEPTION(status)) {
2681 : 0 : return status;
2682 : : }
2683 : : }
2684 : : else {
2685 : : PyWideStringList slice;
2686 : 2871 : slice.length = cmdline_argv->length - opt_index;
2687 : 2871 : slice.items = &cmdline_argv->items[opt_index];
2688 [ - + ]: 2871 : if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2689 : 0 : return _PyStatus_NO_MEMORY();
2690 : : }
2691 : : }
2692 : : assert(config_argv.length >= 1);
2693 : :
2694 : 2903 : wchar_t *arg0 = NULL;
2695 [ + + ]: 2903 : if (config->run_command != NULL) {
2696 : : /* Force sys.argv[0] = '-c' */
2697 : 1627 : arg0 = L"-c";
2698 : : }
2699 [ + + ]: 1276 : else if (config->run_module != NULL) {
2700 : : /* Force sys.argv[0] = '-m'*/
2701 : 873 : arg0 = L"-m";
2702 : : }
2703 : :
2704 [ + + ]: 2903 : if (arg0 != NULL) {
2705 : 2500 : arg0 = _PyMem_RawWcsdup(arg0);
2706 [ - + ]: 2500 : if (arg0 == NULL) {
2707 : 0 : _PyWideStringList_Clear(&config_argv);
2708 : 0 : return _PyStatus_NO_MEMORY();
2709 : : }
2710 : :
2711 : 2500 : PyMem_RawFree(config_argv.items[0]);
2712 : 2500 : config_argv.items[0] = arg0;
2713 : : }
2714 : :
2715 : 2903 : _PyWideStringList_Clear(&config->argv);
2716 : 2903 : config->argv = config_argv;
2717 : 2903 : return _PyStatus_OK();
2718 : : }
2719 : :
2720 : :
2721 : : static PyStatus
2722 : 3053 : core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
2723 : : {
2724 : : PyStatus status;
2725 : :
2726 [ + + ]: 3053 : if (config->parse_argv == 1) {
2727 [ - + ]: 2920 : if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2728 : 0 : return _PyStatus_NO_MEMORY();
2729 : : }
2730 : : }
2731 : :
2732 : : PyPreConfig preconfig;
2733 : :
2734 : 3053 : status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2735 [ - + ]: 3053 : if (_PyStatus_EXCEPTION(status)) {
2736 : 0 : return status;
2737 : : }
2738 : :
2739 : 3053 : _PyPreConfig_GetConfig(&preconfig, config);
2740 : :
2741 : 3053 : status = _PyPreCmdline_Read(precmdline, &preconfig);
2742 [ - + ]: 3053 : if (_PyStatus_EXCEPTION(status)) {
2743 : 0 : return status;
2744 : : }
2745 : :
2746 : 3053 : status = _PyPreCmdline_SetConfig(precmdline, config);
2747 [ - + ]: 3053 : if (_PyStatus_EXCEPTION(status)) {
2748 : 0 : return status;
2749 : : }
2750 : 3053 : return _PyStatus_OK();
2751 : : }
2752 : :
2753 : :
2754 : : /* Get run_filename absolute path */
2755 : : static PyStatus
2756 : 3036 : config_run_filename_abspath(PyConfig *config)
2757 : : {
2758 [ + + ]: 3036 : if (!config->run_filename) {
2759 : 2648 : return _PyStatus_OK();
2760 : : }
2761 : :
2762 : : #ifndef MS_WINDOWS
2763 [ + + ]: 388 : if (_Py_isabs(config->run_filename)) {
2764 : : /* path is already absolute */
2765 : 304 : return _PyStatus_OK();
2766 : : }
2767 : : #endif
2768 : :
2769 : : wchar_t *abs_filename;
2770 [ - + ]: 84 : if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2771 : : /* failed to get the absolute path of the command line filename:
2772 : : ignore the error, keep the relative path */
2773 : 0 : return _PyStatus_OK();
2774 : : }
2775 [ - + ]: 84 : if (abs_filename == NULL) {
2776 : 0 : return _PyStatus_NO_MEMORY();
2777 : : }
2778 : :
2779 : 84 : PyMem_RawFree(config->run_filename);
2780 : 84 : config->run_filename = abs_filename;
2781 : 84 : return _PyStatus_OK();
2782 : : }
2783 : :
2784 : :
2785 : : static PyStatus
2786 : 3053 : config_read_cmdline(PyConfig *config)
2787 : : {
2788 : : PyStatus status;
2789 : 3053 : PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2790 : 3053 : PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2791 : 3053 : PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
2792 : :
2793 [ - + ]: 3053 : if (config->parse_argv < 0) {
2794 : 0 : config->parse_argv = 1;
2795 : : }
2796 : :
2797 [ + + ]: 3053 : if (config->parse_argv == 1) {
2798 : : Py_ssize_t opt_index;
2799 : 2920 : status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2800 [ + + ]: 2920 : if (_PyStatus_EXCEPTION(status)) {
2801 : 17 : goto done;
2802 : : }
2803 : :
2804 : 2903 : status = config_run_filename_abspath(config);
2805 [ - + ]: 2903 : if (_PyStatus_EXCEPTION(status)) {
2806 : 0 : goto done;
2807 : : }
2808 : :
2809 : 2903 : status = config_update_argv(config, opt_index);
2810 [ - + ]: 2903 : if (_PyStatus_EXCEPTION(status)) {
2811 : 0 : goto done;
2812 : : }
2813 : : }
2814 : : else {
2815 : 133 : status = config_run_filename_abspath(config);
2816 [ - + ]: 133 : if (_PyStatus_EXCEPTION(status)) {
2817 : 0 : goto done;
2818 : : }
2819 : : }
2820 : :
2821 [ + + ]: 3036 : if (config->use_environment) {
2822 : 1108 : status = config_init_env_warnoptions(config, &env_warnoptions);
2823 [ - + ]: 1108 : if (_PyStatus_EXCEPTION(status)) {
2824 : 0 : goto done;
2825 : : }
2826 : : }
2827 : :
2828 : : /* Handle early PySys_AddWarnOption() calls */
2829 : 3036 : status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2830 [ - + ]: 3036 : if (_PyStatus_EXCEPTION(status)) {
2831 : 0 : goto done;
2832 : : }
2833 : :
2834 : 3036 : status = config_init_warnoptions(config,
2835 : : &cmdline_warnoptions,
2836 : : &env_warnoptions,
2837 : : &sys_warnoptions);
2838 [ - + ]: 3036 : if (_PyStatus_EXCEPTION(status)) {
2839 : 0 : goto done;
2840 : : }
2841 : :
2842 : 3036 : status = _PyStatus_OK();
2843 : :
2844 : 3053 : done:
2845 : 3053 : _PyWideStringList_Clear(&cmdline_warnoptions);
2846 : 3053 : _PyWideStringList_Clear(&env_warnoptions);
2847 : 3053 : _PyWideStringList_Clear(&sys_warnoptions);
2848 : 3053 : return status;
2849 : : }
2850 : :
2851 : :
2852 : : PyStatus
2853 : 2913 : _PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
2854 : : {
2855 : 2913 : PyStatus status = _Py_PreInitializeFromConfig(config, args);
2856 [ - + ]: 2913 : if (_PyStatus_EXCEPTION(status)) {
2857 : 0 : return status;
2858 : : }
2859 : :
2860 : 2913 : return _PyArgv_AsWstrList(args, &config->argv);
2861 : : }
2862 : :
2863 : :
2864 : : /* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2865 : : if needed to ensure that encodings are properly configured. */
2866 : : PyStatus
2867 : 2886 : PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
2868 : : {
2869 : 2886 : _PyArgv args = {
2870 : : .argc = argc,
2871 : : .use_bytes_argv = 1,
2872 : : .bytes_argv = argv,
2873 : : .wchar_argv = NULL};
2874 : 2886 : return _PyConfig_SetPyArgv(config, &args);
2875 : : }
2876 : :
2877 : :
2878 : : PyStatus
2879 : 27 : PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
2880 : : {
2881 : 27 : _PyArgv args = {
2882 : : .argc = argc,
2883 : : .use_bytes_argv = 0,
2884 : : .bytes_argv = NULL,
2885 : : .wchar_argv = argv};
2886 : 27 : return _PyConfig_SetPyArgv(config, &args);
2887 : : }
2888 : :
2889 : :
2890 : : PyStatus
2891 : 2 : PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2892 : : Py_ssize_t length, wchar_t **items)
2893 : : {
2894 : 2 : PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2895 [ - + ]: 2 : if (_PyStatus_EXCEPTION(status)) {
2896 : 0 : return status;
2897 : : }
2898 : :
2899 : 2 : PyWideStringList list2 = {.length = length, .items = items};
2900 [ - + ]: 2 : if (_PyWideStringList_Copy(list, &list2) < 0) {
2901 : 0 : return _PyStatus_NO_MEMORY();
2902 : : }
2903 : 2 : return _PyStatus_OK();
2904 : : }
2905 : :
2906 : :
2907 : : /* Read the configuration into PyConfig from:
2908 : :
2909 : : * Command line arguments
2910 : : * Environment variables
2911 : : * Py_xxx global configuration variables
2912 : :
2913 : : The only side effects are to modify config and to call _Py_SetArgcArgv(). */
2914 : : PyStatus
2915 : 3053 : _PyConfig_Read(PyConfig *config, int compute_path_config)
2916 : : {
2917 : : PyStatus status;
2918 : :
2919 : 3053 : status = _Py_PreInitializeFromConfig(config, NULL);
2920 [ - + ]: 3053 : if (_PyStatus_EXCEPTION(status)) {
2921 : 0 : return status;
2922 : : }
2923 : :
2924 : 3053 : config_get_global_vars(config);
2925 : :
2926 [ + + ]: 3053 : if (config->orig_argv.length == 0
2927 [ + + ]: 2990 : && !(config->argv.length == 1
2928 [ + + ]: 4 : && wcscmp(config->argv.items[0], L"") == 0))
2929 : : {
2930 [ - + ]: 2989 : if (_PyWideStringList_Copy(&config->orig_argv, &config->argv) < 0) {
2931 : 0 : return _PyStatus_NO_MEMORY();
2932 : : }
2933 : : }
2934 : :
2935 : 3053 : _PyPreCmdline precmdline = _PyPreCmdline_INIT;
2936 : 3053 : status = core_read_precmdline(config, &precmdline);
2937 [ - + ]: 3053 : if (_PyStatus_EXCEPTION(status)) {
2938 : 0 : goto done;
2939 : : }
2940 : :
2941 : : assert(config->isolated >= 0);
2942 [ + + ]: 3053 : if (config->isolated) {
2943 : 729 : config->safe_path = 1;
2944 : 729 : config->use_environment = 0;
2945 : 729 : config->user_site_directory = 0;
2946 : : }
2947 : :
2948 : 3053 : status = config_read_cmdline(config);
2949 [ + + ]: 3053 : if (_PyStatus_EXCEPTION(status)) {
2950 : 17 : goto done;
2951 : : }
2952 : :
2953 : : /* Handle early PySys_AddXOption() calls */
2954 : 3036 : status = _PySys_ReadPreinitXOptions(config);
2955 [ - + ]: 3036 : if (_PyStatus_EXCEPTION(status)) {
2956 : 0 : goto done;
2957 : : }
2958 : :
2959 : 3036 : status = config_read(config, compute_path_config);
2960 [ + + ]: 3036 : if (_PyStatus_EXCEPTION(status)) {
2961 : 3 : goto done;
2962 : : }
2963 : :
2964 : : assert(config_check_consistency(config));
2965 : :
2966 : 3033 : status = _PyStatus_OK();
2967 : :
2968 : 3053 : done:
2969 : 3053 : _PyPreCmdline_Clear(&precmdline);
2970 : 3053 : return status;
2971 : : }
2972 : :
2973 : :
2974 : : PyStatus
2975 : 23 : PyConfig_Read(PyConfig *config)
2976 : : {
2977 : 23 : return _PyConfig_Read(config, 0);
2978 : : }
2979 : :
2980 : :
2981 : : PyObject*
2982 : 41 : _Py_GetConfigsAsDict(void)
2983 : : {
2984 : 41 : PyObject *result = NULL;
2985 : 41 : PyObject *dict = NULL;
2986 : :
2987 : 41 : result = PyDict_New();
2988 [ - + ]: 41 : if (result == NULL) {
2989 : 0 : goto error;
2990 : : }
2991 : :
2992 : : /* global result */
2993 : 41 : dict = _Py_GetGlobalVariablesAsDict();
2994 [ - + ]: 41 : if (dict == NULL) {
2995 : 0 : goto error;
2996 : : }
2997 [ - + ]: 41 : if (PyDict_SetItemString(result, "global_config", dict) < 0) {
2998 : 0 : goto error;
2999 : : }
3000 [ + - ]: 41 : Py_CLEAR(dict);
3001 : :
3002 : : /* pre config */
3003 : 41 : PyInterpreterState *interp = _PyInterpreterState_GET();
3004 : 41 : const PyPreConfig *pre_config = &interp->runtime->preconfig;
3005 : 41 : dict = _PyPreConfig_AsDict(pre_config);
3006 [ - + ]: 41 : if (dict == NULL) {
3007 : 0 : goto error;
3008 : : }
3009 [ - + ]: 41 : if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
3010 : 0 : goto error;
3011 : : }
3012 [ + - ]: 41 : Py_CLEAR(dict);
3013 : :
3014 : : /* core config */
3015 : 41 : const PyConfig *config = _PyInterpreterState_GetConfig(interp);
3016 : 41 : dict = _PyConfig_AsDict(config);
3017 [ - + ]: 41 : if (dict == NULL) {
3018 : 0 : goto error;
3019 : : }
3020 [ - + ]: 41 : if (PyDict_SetItemString(result, "config", dict) < 0) {
3021 : 0 : goto error;
3022 : : }
3023 [ + - ]: 41 : Py_CLEAR(dict);
3024 : :
3025 : 41 : return result;
3026 : :
3027 : 0 : error:
3028 : 0 : Py_XDECREF(result);
3029 : 0 : Py_XDECREF(dict);
3030 : 0 : return NULL;
3031 : : }
3032 : :
3033 : :
3034 : : static void
3035 : 0 : init_dump_ascii_wstr(const wchar_t *str)
3036 : : {
3037 [ # # ]: 0 : if (str == NULL) {
3038 : 0 : PySys_WriteStderr("(not set)");
3039 : 0 : return;
3040 : : }
3041 : :
3042 : 0 : PySys_WriteStderr("'");
3043 [ # # ]: 0 : for (; *str != L'\0'; str++) {
3044 : 0 : unsigned int ch = (unsigned int)*str;
3045 [ # # ]: 0 : if (ch == L'\'') {
3046 : 0 : PySys_WriteStderr("\\'");
3047 [ # # # # ]: 0 : } else if (0x20 <= ch && ch < 0x7f) {
3048 : 0 : PySys_WriteStderr("%c", ch);
3049 : : }
3050 [ # # ]: 0 : else if (ch <= 0xff) {
3051 : 0 : PySys_WriteStderr("\\x%02x", ch);
3052 : : }
3053 : : #if SIZEOF_WCHAR_T > 2
3054 [ # # ]: 0 : else if (ch > 0xffff) {
3055 : 0 : PySys_WriteStderr("\\U%08x", ch);
3056 : : }
3057 : : #endif
3058 : : else {
3059 : 0 : PySys_WriteStderr("\\u%04x", ch);
3060 : : }
3061 : : }
3062 : 0 : PySys_WriteStderr("'");
3063 : : }
3064 : :
3065 : :
3066 : : /* Dump the Python path configuration into sys.stderr */
3067 : : void
3068 : 0 : _Py_DumpPathConfig(PyThreadState *tstate)
3069 : : {
3070 : : PyObject *exc_type, *exc_value, *exc_tb;
3071 : 0 : _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
3072 : :
3073 : 0 : PySys_WriteStderr("Python path configuration:\n");
3074 : :
3075 : : #define DUMP_CONFIG(NAME, FIELD) \
3076 : : do { \
3077 : : PySys_WriteStderr(" " NAME " = "); \
3078 : : init_dump_ascii_wstr(config->FIELD); \
3079 : : PySys_WriteStderr("\n"); \
3080 : : } while (0)
3081 : :
3082 : 0 : const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
3083 : 0 : DUMP_CONFIG("PYTHONHOME", home);
3084 : 0 : DUMP_CONFIG("PYTHONPATH", pythonpath_env);
3085 : 0 : DUMP_CONFIG("program name", program_name);
3086 : 0 : PySys_WriteStderr(" isolated = %i\n", config->isolated);
3087 : 0 : PySys_WriteStderr(" environment = %i\n", config->use_environment);
3088 : 0 : PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
3089 : 0 : PySys_WriteStderr(" safe_path = %i\n", config->safe_path);
3090 : 0 : PySys_WriteStderr(" import site = %i\n", config->site_import);
3091 : 0 : PySys_WriteStderr(" is in build tree = %i\n", config->_is_python_build);
3092 : 0 : DUMP_CONFIG("stdlib dir", stdlib_dir);
3093 : : #undef DUMP_CONFIG
3094 : :
3095 : : #define DUMP_SYS(NAME) \
3096 : : do { \
3097 : : obj = PySys_GetObject(#NAME); \
3098 : : PySys_FormatStderr(" sys.%s = ", #NAME); \
3099 : : if (obj != NULL) { \
3100 : : PySys_FormatStderr("%A", obj); \
3101 : : } \
3102 : : else { \
3103 : : PySys_WriteStderr("(not set)"); \
3104 : : } \
3105 : : PySys_FormatStderr("\n"); \
3106 : : } while (0)
3107 : :
3108 : : PyObject *obj;
3109 [ # # ]: 0 : DUMP_SYS(_base_executable);
3110 [ # # ]: 0 : DUMP_SYS(base_prefix);
3111 [ # # ]: 0 : DUMP_SYS(base_exec_prefix);
3112 [ # # ]: 0 : DUMP_SYS(platlibdir);
3113 [ # # ]: 0 : DUMP_SYS(executable);
3114 [ # # ]: 0 : DUMP_SYS(prefix);
3115 [ # # ]: 0 : DUMP_SYS(exec_prefix);
3116 : : #undef DUMP_SYS
3117 : :
3118 : 0 : PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
3119 [ # # # # ]: 0 : if (sys_path != NULL && PyList_Check(sys_path)) {
3120 : 0 : PySys_WriteStderr(" sys.path = [\n");
3121 : 0 : Py_ssize_t len = PyList_GET_SIZE(sys_path);
3122 [ # # ]: 0 : for (Py_ssize_t i=0; i < len; i++) {
3123 : 0 : PyObject *path = PyList_GET_ITEM(sys_path, i);
3124 : 0 : PySys_FormatStderr(" %A,\n", path);
3125 : : }
3126 : 0 : PySys_WriteStderr(" ]\n");
3127 : : }
3128 : :
3129 : 0 : _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
3130 : 0 : }
|