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