You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1358 lines
38 KiB

  1. #include "Python.h"
  2. #include "internal/mem.h"
  3. #include "internal/pystate.h"
  4. #include <locale.h>
  5. #ifdef HAVE_LANGINFO_H
  6. # include <langinfo.h>
  7. #endif
  8. #include <locale.h> /* setlocale() */
  9. #ifdef HAVE_LANGINFO_H
  10. #include <langinfo.h> /* nl_langinfo(CODESET) */
  11. #endif
  12. #define DECODE_LOCALE_ERR(NAME, LEN) \
  13. (((LEN) == -2) \
  14. ? _Py_INIT_USER_ERR("cannot decode " NAME) \
  15. : _Py_INIT_NO_MEMORY())
  16. /* Global configuration variables */
  17. /* The filesystem encoding is chosen by config_init_fs_encoding(),
  18. see also initfsencoding(). */
  19. const char *Py_FileSystemDefaultEncoding = NULL;
  20. int Py_HasFileSystemDefaultEncoding = 0;
  21. const char *Py_FileSystemDefaultEncodeErrors = NULL;
  22. static int _Py_HasFileSystemDefaultEncodeErrors = 0;
  23. /* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
  24. stdin and stdout error handler to "surrogateescape". It is equal to
  25. -1 by default: unknown, will be set by Py_Main() */
  26. int Py_UTF8Mode = -1;
  27. int Py_DebugFlag = 0; /* Needed by parser.c */
  28. int Py_VerboseFlag = 0; /* Needed by import.c */
  29. int Py_QuietFlag = 0; /* Needed by sysmodule.c */
  30. int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
  31. int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
  32. int Py_OptimizeFlag = 0; /* Needed by compile.c */
  33. int Py_NoSiteFlag = 0; /* Suppress 'import site' */
  34. int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
  35. int Py_FrozenFlag = 0; /* Needed by getpath.c */
  36. int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
  37. int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
  38. int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
  39. int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
  40. int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
  41. int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
  42. #ifdef MS_WINDOWS
  43. int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
  44. int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
  45. #endif
  46. void
  47. _Py_wstrlist_clear(int len, wchar_t **list)
  48. {
  49. for (int i=0; i < len; i++) {
  50. PyMem_RawFree(list[i]);
  51. }
  52. PyMem_RawFree(list);
  53. }
  54. wchar_t**
  55. _Py_wstrlist_copy(int len, wchar_t **list)
  56. {
  57. assert((len > 0 && list != NULL) || len == 0);
  58. size_t size = len * sizeof(list[0]);
  59. wchar_t **list_copy = PyMem_RawMalloc(size);
  60. if (list_copy == NULL) {
  61. return NULL;
  62. }
  63. for (int i=0; i < len; i++) {
  64. wchar_t* arg = _PyMem_RawWcsdup(list[i]);
  65. if (arg == NULL) {
  66. _Py_wstrlist_clear(i, list_copy);
  67. return NULL;
  68. }
  69. list_copy[i] = arg;
  70. }
  71. return list_copy;
  72. }
  73. void
  74. _Py_ClearFileSystemEncoding(void)
  75. {
  76. if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) {
  77. PyMem_RawFree((char*)Py_FileSystemDefaultEncoding);
  78. Py_FileSystemDefaultEncoding = NULL;
  79. }
  80. if (!_Py_HasFileSystemDefaultEncodeErrors && Py_FileSystemDefaultEncodeErrors) {
  81. PyMem_RawFree((char*)Py_FileSystemDefaultEncodeErrors);
  82. Py_FileSystemDefaultEncodeErrors = NULL;
  83. }
  84. }
  85. /* Set Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors
  86. global configuration variables. */
  87. int
  88. _Py_SetFileSystemEncoding(const char *encoding, const char *errors)
  89. {
  90. char *encoding2 = _PyMem_RawStrdup(encoding);
  91. if (encoding2 == NULL) {
  92. return -1;
  93. }
  94. char *errors2 = _PyMem_RawStrdup(errors);
  95. if (errors2 == NULL) {
  96. PyMem_RawFree(encoding2);
  97. return -1;
  98. }
  99. _Py_ClearFileSystemEncoding();
  100. Py_FileSystemDefaultEncoding = encoding2;
  101. Py_HasFileSystemDefaultEncoding = 0;
  102. Py_FileSystemDefaultEncodeErrors = errors2;
  103. _Py_HasFileSystemDefaultEncodeErrors = 0;
  104. return 0;
  105. }
  106. /* Helper to allow an embedding application to override the normal
  107. * mechanism that attempts to figure out an appropriate IO encoding
  108. */
  109. static char *_Py_StandardStreamEncoding = NULL;
  110. static char *_Py_StandardStreamErrors = NULL;
  111. int
  112. Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
  113. {
  114. if (Py_IsInitialized()) {
  115. /* This is too late to have any effect */
  116. return -1;
  117. }
  118. int res = 0;
  119. /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
  120. but Py_Initialize() can change the allocator. Use a known allocator
  121. to be able to release the memory later. */
  122. PyMemAllocatorEx old_alloc;
  123. _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  124. /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
  125. * initialised yet.
  126. *
  127. * However, the raw memory allocators are initialised appropriately
  128. * as C static variables, so _PyMem_RawStrdup is OK even though
  129. * Py_Initialize hasn't been called yet.
  130. */
  131. if (encoding) {
  132. _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
  133. if (!_Py_StandardStreamEncoding) {
  134. res = -2;
  135. goto done;
  136. }
  137. }
  138. if (errors) {
  139. _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
  140. if (!_Py_StandardStreamErrors) {
  141. if (_Py_StandardStreamEncoding) {
  142. PyMem_RawFree(_Py_StandardStreamEncoding);
  143. }
  144. res = -3;
  145. goto done;
  146. }
  147. }
  148. #ifdef MS_WINDOWS
  149. if (_Py_StandardStreamEncoding) {
  150. /* Overriding the stream encoding implies legacy streams */
  151. Py_LegacyWindowsStdioFlag = 1;
  152. }
  153. #endif
  154. done:
  155. PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  156. return res;
  157. }
  158. void
  159. _Py_ClearStandardStreamEncoding(void)
  160. {
  161. /* Use the same allocator than Py_SetStandardStreamEncoding() */
  162. PyMemAllocatorEx old_alloc;
  163. _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  164. /* We won't need them anymore. */
  165. if (_Py_StandardStreamEncoding) {
  166. PyMem_RawFree(_Py_StandardStreamEncoding);
  167. _Py_StandardStreamEncoding = NULL;
  168. }
  169. if (_Py_StandardStreamErrors) {
  170. PyMem_RawFree(_Py_StandardStreamErrors);
  171. _Py_StandardStreamErrors = NULL;
  172. }
  173. PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  174. }
  175. /* Free memory allocated in config, but don't clear all attributes */
  176. void
  177. _PyCoreConfig_Clear(_PyCoreConfig *config)
  178. {
  179. #define CLEAR(ATTR) \
  180. do { \
  181. PyMem_RawFree(ATTR); \
  182. ATTR = NULL; \
  183. } while (0)
  184. #define CLEAR_WSTRLIST(LEN, LIST) \
  185. do { \
  186. _Py_wstrlist_clear(LEN, LIST); \
  187. LEN = 0; \
  188. LIST = NULL; \
  189. } while (0)
  190. CLEAR(config->pycache_prefix);
  191. CLEAR(config->module_search_path_env);
  192. CLEAR(config->home);
  193. CLEAR(config->program_name);
  194. CLEAR(config->program);
  195. CLEAR_WSTRLIST(config->argc, config->argv);
  196. config->argc = -1;
  197. CLEAR_WSTRLIST(config->nwarnoption, config->warnoptions);
  198. CLEAR_WSTRLIST(config->nxoption, config->xoptions);
  199. CLEAR_WSTRLIST(config->nmodule_search_path, config->module_search_paths);
  200. config->nmodule_search_path = -1;
  201. CLEAR(config->executable);
  202. CLEAR(config->prefix);
  203. CLEAR(config->base_prefix);
  204. CLEAR(config->exec_prefix);
  205. #ifdef MS_WINDOWS
  206. CLEAR(config->dll_path);
  207. #endif
  208. CLEAR(config->base_exec_prefix);
  209. CLEAR(config->filesystem_encoding);
  210. CLEAR(config->filesystem_errors);
  211. CLEAR(config->stdio_encoding);
  212. CLEAR(config->stdio_errors);
  213. #undef CLEAR
  214. #undef CLEAR_WSTRLIST
  215. }
  216. int
  217. _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
  218. {
  219. _PyCoreConfig_Clear(config);
  220. #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
  221. #define COPY_STR_ATTR(ATTR) \
  222. do { \
  223. if (config2->ATTR != NULL) { \
  224. config->ATTR = _PyMem_RawStrdup(config2->ATTR); \
  225. if (config->ATTR == NULL) { \
  226. return -1; \
  227. } \
  228. } \
  229. } while (0)
  230. #define COPY_WSTR_ATTR(ATTR) \
  231. do { \
  232. if (config2->ATTR != NULL) { \
  233. config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \
  234. if (config->ATTR == NULL) { \
  235. return -1; \
  236. } \
  237. } \
  238. } while (0)
  239. #define COPY_WSTRLIST(LEN, LIST) \
  240. do { \
  241. if (config2->LIST != NULL) { \
  242. config->LIST = _Py_wstrlist_copy(config2->LEN, config2->LIST); \
  243. if (config->LIST == NULL) { \
  244. return -1; \
  245. } \
  246. } \
  247. config->LEN = config2->LEN; \
  248. } while (0)
  249. COPY_ATTR(install_signal_handlers);
  250. COPY_ATTR(use_environment);
  251. COPY_ATTR(use_hash_seed);
  252. COPY_ATTR(hash_seed);
  253. COPY_ATTR(_install_importlib);
  254. COPY_ATTR(allocator);
  255. COPY_ATTR(dev_mode);
  256. COPY_ATTR(faulthandler);
  257. COPY_ATTR(tracemalloc);
  258. COPY_ATTR(import_time);
  259. COPY_ATTR(show_ref_count);
  260. COPY_ATTR(show_alloc_count);
  261. COPY_ATTR(dump_refs);
  262. COPY_ATTR(malloc_stats);
  263. COPY_ATTR(coerce_c_locale);
  264. COPY_ATTR(coerce_c_locale_warn);
  265. COPY_ATTR(utf8_mode);
  266. COPY_WSTR_ATTR(pycache_prefix);
  267. COPY_WSTR_ATTR(module_search_path_env);
  268. COPY_WSTR_ATTR(home);
  269. COPY_WSTR_ATTR(program_name);
  270. COPY_WSTR_ATTR(program);
  271. COPY_WSTRLIST(argc, argv);
  272. COPY_WSTRLIST(nwarnoption, warnoptions);
  273. COPY_WSTRLIST(nxoption, xoptions);
  274. COPY_WSTRLIST(nmodule_search_path, module_search_paths);
  275. COPY_WSTR_ATTR(executable);
  276. COPY_WSTR_ATTR(prefix);
  277. COPY_WSTR_ATTR(base_prefix);
  278. COPY_WSTR_ATTR(exec_prefix);
  279. #ifdef MS_WINDOWS
  280. COPY_WSTR_ATTR(dll_path);
  281. #endif
  282. COPY_WSTR_ATTR(base_exec_prefix);
  283. COPY_ATTR(isolated);
  284. COPY_ATTR(site_import);
  285. COPY_ATTR(bytes_warning);
  286. COPY_ATTR(inspect);
  287. COPY_ATTR(interactive);
  288. COPY_ATTR(optimization_level);
  289. COPY_ATTR(parser_debug);
  290. COPY_ATTR(write_bytecode);
  291. COPY_ATTR(verbose);
  292. COPY_ATTR(quiet);
  293. COPY_ATTR(user_site_directory);
  294. COPY_ATTR(buffered_stdio);
  295. COPY_STR_ATTR(filesystem_encoding);
  296. COPY_STR_ATTR(filesystem_errors);
  297. COPY_STR_ATTR(stdio_encoding);
  298. COPY_STR_ATTR(stdio_errors);
  299. #ifdef MS_WINDOWS
  300. COPY_ATTR(legacy_windows_fs_encoding);
  301. COPY_ATTR(legacy_windows_stdio);
  302. #endif
  303. COPY_ATTR(_check_hash_pycs_mode);
  304. COPY_ATTR(_frozen);
  305. #undef COPY_ATTR
  306. #undef COPY_STR_ATTR
  307. #undef COPY_WSTR_ATTR
  308. #undef COPY_WSTRLIST
  309. return 0;
  310. }
  311. const char*
  312. _PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name)
  313. {
  314. assert(config->use_environment >= 0);
  315. if (!config->use_environment) {
  316. return NULL;
  317. }
  318. const char *var = getenv(name);
  319. if (var && var[0] != '\0') {
  320. return var;
  321. }
  322. else {
  323. return NULL;
  324. }
  325. }
  326. int
  327. _PyCoreConfig_GetEnvDup(const _PyCoreConfig *config,
  328. wchar_t **dest,
  329. wchar_t *wname, char *name)
  330. {
  331. assert(config->use_environment >= 0);
  332. if (!config->use_environment) {
  333. *dest = NULL;
  334. return 0;
  335. }
  336. #ifdef MS_WINDOWS
  337. const wchar_t *var = _wgetenv(wname);
  338. if (!var || var[0] == '\0') {
  339. *dest = NULL;
  340. return 0;
  341. }
  342. wchar_t *copy = _PyMem_RawWcsdup(var);
  343. if (copy == NULL) {
  344. return -1;
  345. }
  346. *dest = copy;
  347. #else
  348. const char *var = getenv(name);
  349. if (!var || var[0] == '\0') {
  350. *dest = NULL;
  351. return 0;
  352. }
  353. size_t len;
  354. wchar_t *wvar = Py_DecodeLocale(var, &len);
  355. if (!wvar) {
  356. if (len == (size_t)-2) {
  357. return -2;
  358. }
  359. else {
  360. return -1;
  361. }
  362. }
  363. *dest = wvar;
  364. #endif
  365. return 0;
  366. }
  367. void
  368. _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
  369. {
  370. #define COPY_FLAG(ATTR, VALUE) \
  371. if (config->ATTR == -1) { \
  372. config->ATTR = VALUE; \
  373. }
  374. #define COPY_NOT_FLAG(ATTR, VALUE) \
  375. if (config->ATTR == -1) { \
  376. config->ATTR = !(VALUE); \
  377. }
  378. COPY_FLAG(utf8_mode, Py_UTF8Mode);
  379. COPY_FLAG(isolated, Py_IsolatedFlag);
  380. COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
  381. COPY_FLAG(inspect, Py_InspectFlag);
  382. COPY_FLAG(interactive, Py_InteractiveFlag);
  383. COPY_FLAG(optimization_level, Py_OptimizeFlag);
  384. COPY_FLAG(parser_debug, Py_DebugFlag);
  385. COPY_FLAG(verbose, Py_VerboseFlag);
  386. COPY_FLAG(quiet, Py_QuietFlag);
  387. #ifdef MS_WINDOWS
  388. COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
  389. COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
  390. #endif
  391. COPY_FLAG(_frozen, Py_FrozenFlag);
  392. COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
  393. COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
  394. COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
  395. COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
  396. COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
  397. #undef COPY_FLAG
  398. #undef COPY_NOT_FLAG
  399. }
  400. /* Set Py_xxx global configuration variables from 'config' configuration. */
  401. void
  402. _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
  403. {
  404. #define COPY_FLAG(ATTR, VAR) \
  405. if (config->ATTR != -1) { \
  406. VAR = config->ATTR; \
  407. }
  408. #define COPY_NOT_FLAG(ATTR, VAR) \
  409. if (config->ATTR != -1) { \
  410. VAR = !config->ATTR; \
  411. }
  412. COPY_FLAG(utf8_mode, Py_UTF8Mode);
  413. COPY_FLAG(isolated, Py_IsolatedFlag);
  414. COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
  415. COPY_FLAG(inspect, Py_InspectFlag);
  416. COPY_FLAG(interactive, Py_InteractiveFlag);
  417. COPY_FLAG(optimization_level, Py_OptimizeFlag);
  418. COPY_FLAG(parser_debug, Py_DebugFlag);
  419. COPY_FLAG(verbose, Py_VerboseFlag);
  420. COPY_FLAG(quiet, Py_QuietFlag);
  421. #ifdef MS_WINDOWS
  422. COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
  423. COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
  424. #endif
  425. COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
  426. COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
  427. COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
  428. COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
  429. COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
  430. /* Random or non-zero hash seed */
  431. Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
  432. config->hash_seed != 0);
  433. #undef COPY_FLAG
  434. #undef COPY_NOT_FLAG
  435. }
  436. /* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
  437. environment variables on macOS if available. */
  438. static _PyInitError
  439. config_init_program_name(_PyCoreConfig *config)
  440. {
  441. assert(config->program_name == NULL);
  442. /* If Py_SetProgramName() was called, use its value */
  443. const wchar_t *program_name = _Py_path_config.program_name;
  444. if (program_name != NULL) {
  445. config->program_name = _PyMem_RawWcsdup(program_name);
  446. if (config->program_name == NULL) {
  447. return _Py_INIT_NO_MEMORY();
  448. }
  449. return _Py_INIT_OK();
  450. }
  451. #ifdef __APPLE__
  452. /* On MacOS X, when the Python interpreter is embedded in an
  453. application bundle, it gets executed by a bootstrapping script
  454. that does os.execve() with an argv[0] that's different from the
  455. actual Python executable. This is needed to keep the Finder happy,
  456. or rather, to work around Apple's overly strict requirements of
  457. the process name. However, we still need a usable sys.executable,
  458. so the actual executable path is passed in an environment variable.
  459. See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
  460. script. */
  461. const char *p = _PyCoreConfig_GetEnv(config, "PYTHONEXECUTABLE");
  462. if (p != NULL) {
  463. size_t len;
  464. wchar_t* program_name = Py_DecodeLocale(p, &len);
  465. if (program_name == NULL) {
  466. return DECODE_LOCALE_ERR("PYTHONEXECUTABLE environment "
  467. "variable", (Py_ssize_t)len);
  468. }
  469. config->program_name = program_name;
  470. return _Py_INIT_OK();
  471. }
  472. #ifdef WITH_NEXT_FRAMEWORK
  473. else {
  474. const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
  475. if (pyvenv_launcher && *pyvenv_launcher) {
  476. /* Used by Mac/Tools/pythonw.c to forward
  477. * the argv0 of the stub executable
  478. */
  479. size_t len;
  480. wchar_t* program_name = Py_DecodeLocale(pyvenv_launcher, &len);
  481. if (program_name == NULL) {
  482. return DECODE_LOCALE_ERR("__PYVENV_LAUNCHER__ environment "
  483. "variable", (Py_ssize_t)len);
  484. }
  485. config->program_name = program_name;
  486. return _Py_INIT_OK();
  487. }
  488. }
  489. #endif /* WITH_NEXT_FRAMEWORK */
  490. #endif /* __APPLE__ */
  491. /* Use argv[0] by default, if available */
  492. if (config->program != NULL) {
  493. config->program_name = _PyMem_RawWcsdup(config->program);
  494. if (config->program_name == NULL) {
  495. return _Py_INIT_NO_MEMORY();
  496. }
  497. return _Py_INIT_OK();
  498. }
  499. /* Last fall back: hardcoded string */
  500. #ifdef MS_WINDOWS
  501. const wchar_t *default_program_name = L"python";
  502. #else
  503. const wchar_t *default_program_name = L"python3";
  504. #endif
  505. config->program_name = _PyMem_RawWcsdup(default_program_name);
  506. if (config->program_name == NULL) {
  507. return _Py_INIT_NO_MEMORY();
  508. }
  509. return _Py_INIT_OK();
  510. }
  511. static const wchar_t*
  512. config_get_xoption(const _PyCoreConfig *config, wchar_t *name)
  513. {
  514. int nxoption = config->nxoption;
  515. wchar_t **xoptions = config->xoptions;
  516. for (int i=0; i < nxoption; i++) {
  517. wchar_t *option = xoptions[i];
  518. size_t len;
  519. wchar_t *sep = wcschr(option, L'=');
  520. if (sep != NULL) {
  521. len = (sep - option);
  522. }
  523. else {
  524. len = wcslen(option);
  525. }
  526. if (wcsncmp(option, name, len) == 0 && name[len] == L'\0') {
  527. return option;
  528. }
  529. }
  530. return NULL;
  531. }
  532. static _PyInitError
  533. config_init_home(_PyCoreConfig *config)
  534. {
  535. wchar_t *home;
  536. /* If Py_SetPythonHome() was called, use its value */
  537. home = _Py_path_config.home;
  538. if (home) {
  539. config->home = _PyMem_RawWcsdup(home);
  540. if (config->home == NULL) {
  541. return _Py_INIT_NO_MEMORY();
  542. }
  543. return _Py_INIT_OK();
  544. }
  545. int res = _PyCoreConfig_GetEnvDup(config, &home,
  546. L"PYTHONHOME", "PYTHONHOME");
  547. if (res < 0) {
  548. return DECODE_LOCALE_ERR("PYTHONHOME", res);
  549. }
  550. config->home = home;
  551. return _Py_INIT_OK();
  552. }
  553. static _PyInitError
  554. config_init_hash_seed(_PyCoreConfig *config)
  555. {
  556. const char *seed_text = _PyCoreConfig_GetEnv(config, "PYTHONHASHSEED");
  557. Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
  558. /* Convert a text seed to a numeric one */
  559. if (seed_text && strcmp(seed_text, "random") != 0) {
  560. const char *endptr = seed_text;
  561. unsigned long seed;
  562. errno = 0;
  563. seed = strtoul(seed_text, (char **)&endptr, 10);
  564. if (*endptr != '\0'
  565. || seed > 4294967295UL
  566. || (errno == ERANGE && seed == ULONG_MAX))
  567. {
  568. return _Py_INIT_USER_ERR("PYTHONHASHSEED must be \"random\" "
  569. "or an integer in range [0; 4294967295]");
  570. }
  571. /* Use a specific hash */
  572. config->use_hash_seed = 1;
  573. config->hash_seed = seed;
  574. }
  575. else {
  576. /* Use a random hash */
  577. config->use_hash_seed = 0;
  578. config->hash_seed = 0;
  579. }
  580. return _Py_INIT_OK();
  581. }
  582. static _PyInitError
  583. config_init_utf8_mode(_PyCoreConfig *config)
  584. {
  585. const wchar_t *xopt = config_get_xoption(config, L"utf8");
  586. if (xopt) {
  587. wchar_t *sep = wcschr(xopt, L'=');
  588. if (sep) {
  589. xopt = sep + 1;
  590. if (wcscmp(xopt, L"1") == 0) {
  591. config->utf8_mode = 1;
  592. }
  593. else if (wcscmp(xopt, L"0") == 0) {
  594. config->utf8_mode = 0;
  595. }
  596. else {
  597. return _Py_INIT_USER_ERR("invalid -X utf8 option value");
  598. }
  599. }
  600. else {
  601. config->utf8_mode = 1;
  602. }
  603. return _Py_INIT_OK();
  604. }
  605. const char *opt = _PyCoreConfig_GetEnv(config, "PYTHONUTF8");
  606. if (opt) {
  607. if (strcmp(opt, "1") == 0) {
  608. config->utf8_mode = 1;
  609. }
  610. else if (strcmp(opt, "0") == 0) {
  611. config->utf8_mode = 0;
  612. }
  613. else {
  614. return _Py_INIT_USER_ERR("invalid PYTHONUTF8 environment "
  615. "variable value");
  616. }
  617. return _Py_INIT_OK();
  618. }
  619. return _Py_INIT_OK();
  620. }
  621. static int
  622. config_str_to_int(const char *str, int *result)
  623. {
  624. const char *endptr = str;
  625. errno = 0;
  626. long value = strtol(str, (char **)&endptr, 10);
  627. if (*endptr != '\0' || errno == ERANGE) {
  628. return -1;
  629. }
  630. if (value < INT_MIN || value > INT_MAX) {
  631. return -1;
  632. }
  633. *result = (int)value;
  634. return 0;
  635. }
  636. static int
  637. config_wstr_to_int(const wchar_t *wstr, int *result)
  638. {
  639. const wchar_t *endptr = wstr;
  640. errno = 0;
  641. long value = wcstol(wstr, (wchar_t **)&endptr, 10);
  642. if (*endptr != '\0' || errno == ERANGE) {
  643. return -1;
  644. }
  645. if (value < INT_MIN || value > INT_MAX) {
  646. return -1;
  647. }
  648. *result = (int)value;
  649. return 0;
  650. }
  651. static void
  652. get_env_flag(_PyCoreConfig *config, int *flag, const char *name)
  653. {
  654. const char *var = _PyCoreConfig_GetEnv(config, name);
  655. if (!var) {
  656. return;
  657. }
  658. int value;
  659. if (config_str_to_int(var, &value) < 0 || value < 0) {
  660. /* PYTHONDEBUG=text and PYTHONDEBUG=-2 behave as PYTHONDEBUG=1 */
  661. value = 1;
  662. }
  663. if (*flag < value) {
  664. *flag = value;
  665. }
  666. }
  667. static _PyInitError
  668. config_read_env_vars(_PyCoreConfig *config)
  669. {
  670. /* Get environment variables */
  671. get_env_flag(config, &config->parser_debug, "PYTHONDEBUG");
  672. get_env_flag(config, &config->verbose, "PYTHONVERBOSE");
  673. get_env_flag(config, &config->optimization_level, "PYTHONOPTIMIZE");
  674. get_env_flag(config, &config->inspect, "PYTHONINSPECT");
  675. int dont_write_bytecode = 0;
  676. get_env_flag(config, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
  677. if (dont_write_bytecode) {
  678. config->write_bytecode = 0;
  679. }
  680. int no_user_site_directory = 0;
  681. get_env_flag(config, &no_user_site_directory, "PYTHONNOUSERSITE");
  682. if (no_user_site_directory) {
  683. config->user_site_directory = 0;
  684. }
  685. int unbuffered_stdio = 0;
  686. get_env_flag(config, &unbuffered_stdio, "PYTHONUNBUFFERED");
  687. if (unbuffered_stdio) {
  688. config->buffered_stdio = 0;
  689. }
  690. #ifdef MS_WINDOWS
  691. get_env_flag(config, &config->legacy_windows_fs_encoding,
  692. "PYTHONLEGACYWINDOWSFSENCODING");
  693. get_env_flag(config, &config->legacy_windows_stdio,
  694. "PYTHONLEGACYWINDOWSSTDIO");
  695. #endif
  696. if (config->allocator == NULL) {
  697. config->allocator = _PyCoreConfig_GetEnv(config, "PYTHONMALLOC");
  698. }
  699. if (_PyCoreConfig_GetEnv(config, "PYTHONDUMPREFS")) {
  700. config->dump_refs = 1;
  701. }
  702. if (_PyCoreConfig_GetEnv(config, "PYTHONMALLOCSTATS")) {
  703. config->malloc_stats = 1;
  704. }
  705. const char *env = _PyCoreConfig_GetEnv(config, "PYTHONCOERCECLOCALE");
  706. if (env) {
  707. if (strcmp(env, "0") == 0) {
  708. if (config->coerce_c_locale < 0) {
  709. config->coerce_c_locale = 0;
  710. }
  711. }
  712. else if (strcmp(env, "warn") == 0) {
  713. config->coerce_c_locale_warn = 1;
  714. }
  715. else {
  716. if (config->coerce_c_locale < 0) {
  717. config->coerce_c_locale = 1;
  718. }
  719. }
  720. }
  721. wchar_t *path;
  722. int res = _PyCoreConfig_GetEnvDup(config, &path,
  723. L"PYTHONPATH", "PYTHONPATH");
  724. if (res < 0) {
  725. return DECODE_LOCALE_ERR("PYTHONPATH", res);
  726. }
  727. config->module_search_path_env = path;
  728. if (config->use_hash_seed < 0) {
  729. _PyInitError err = config_init_hash_seed(config);
  730. if (_Py_INIT_FAILED(err)) {
  731. return err;
  732. }
  733. }
  734. return _Py_INIT_OK();
  735. }
  736. static _PyInitError
  737. config_init_tracemalloc(_PyCoreConfig *config)
  738. {
  739. int nframe;
  740. int valid;
  741. const char *env = _PyCoreConfig_GetEnv(config, "PYTHONTRACEMALLOC");
  742. if (env) {
  743. if (!config_str_to_int(env, &nframe)) {
  744. valid = (nframe >= 0);
  745. }
  746. else {
  747. valid = 0;
  748. }
  749. if (!valid) {
  750. return _Py_INIT_USER_ERR("PYTHONTRACEMALLOC: invalid number "
  751. "of frames");
  752. }
  753. config->tracemalloc = nframe;
  754. }
  755. const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
  756. if (xoption) {
  757. const wchar_t *sep = wcschr(xoption, L'=');
  758. if (sep) {
  759. if (!config_wstr_to_int(sep + 1, &nframe)) {
  760. valid = (nframe >= 0);
  761. }
  762. else {
  763. valid = 0;
  764. }
  765. if (!valid) {
  766. return _Py_INIT_USER_ERR("-X tracemalloc=NFRAME: "
  767. "invalid number of frames");
  768. }
  769. }
  770. else {
  771. /* -X tracemalloc behaves as -X tracemalloc=1 */
  772. nframe = 1;
  773. }
  774. config->tracemalloc = nframe;
  775. }
  776. return _Py_INIT_OK();
  777. }
  778. static _PyInitError
  779. config_init_pycache_prefix(_PyCoreConfig *config)
  780. {
  781. assert(config->pycache_prefix == NULL);
  782. const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
  783. if (xoption) {
  784. const wchar_t *sep = wcschr(xoption, L'=');
  785. if (sep && wcslen(sep) > 1) {
  786. config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
  787. if (config->pycache_prefix == NULL) {
  788. return _Py_INIT_NO_MEMORY();
  789. }
  790. }
  791. else {
  792. // -X pycache_prefix= can cancel the env var
  793. config->pycache_prefix = NULL;
  794. }
  795. }
  796. else {
  797. wchar_t *env;
  798. int res = _PyCoreConfig_GetEnvDup(config, &env,
  799. L"PYTHONPYCACHEPREFIX",
  800. "PYTHONPYCACHEPREFIX");
  801. if (res < 0) {
  802. return DECODE_LOCALE_ERR("PYTHONPYCACHEPREFIX", res);
  803. }
  804. if (env) {
  805. config->pycache_prefix = env;
  806. }
  807. }
  808. return _Py_INIT_OK();
  809. }
  810. static _PyInitError
  811. config_read_complex_options(_PyCoreConfig *config)
  812. {
  813. /* More complex options configured by env var and -X option */
  814. if (config->faulthandler < 0) {
  815. if (_PyCoreConfig_GetEnv(config, "PYTHONFAULTHANDLER")
  816. || config_get_xoption(config, L"faulthandler")) {
  817. config->faulthandler = 1;
  818. }
  819. }
  820. if (_PyCoreConfig_GetEnv(config, "PYTHONPROFILEIMPORTTIME")
  821. || config_get_xoption(config, L"importtime")) {
  822. config->import_time = 1;
  823. }
  824. if (config_get_xoption(config, L"dev" ) ||
  825. _PyCoreConfig_GetEnv(config, "PYTHONDEVMODE"))
  826. {
  827. config->dev_mode = 1;
  828. }
  829. _PyInitError err;
  830. if (config->tracemalloc < 0) {
  831. err = config_init_tracemalloc(config);
  832. if (_Py_INIT_FAILED(err)) {
  833. return err;
  834. }
  835. }
  836. if (config->pycache_prefix == NULL) {
  837. err = config_init_pycache_prefix(config);
  838. if (_Py_INIT_FAILED(err)) {
  839. return err;
  840. }
  841. }
  842. return _Py_INIT_OK();
  843. }
  844. static void
  845. config_init_locale(_PyCoreConfig *config)
  846. {
  847. if (config->coerce_c_locale < 0) {
  848. /* The C locale enables the C locale coercion (PEP 538) */
  849. if (_Py_LegacyLocaleDetected()) {
  850. config->coerce_c_locale = 1;
  851. }
  852. }
  853. #ifndef MS_WINDOWS
  854. if (config->utf8_mode < 0) {
  855. /* The C locale and the POSIX locale enable the UTF-8 Mode (PEP 540) */
  856. const char *ctype_loc = setlocale(LC_CTYPE, NULL);
  857. if (ctype_loc != NULL
  858. && (strcmp(ctype_loc, "C") == 0
  859. || strcmp(ctype_loc, "POSIX") == 0))
  860. {
  861. config->utf8_mode = 1;
  862. }
  863. }
  864. #endif
  865. }
  866. static const char *
  867. get_stdio_errors(const _PyCoreConfig *config)
  868. {
  869. #ifndef MS_WINDOWS
  870. const char *loc = setlocale(LC_CTYPE, NULL);
  871. if (loc != NULL) {
  872. /* surrogateescape is the default in the legacy C and POSIX locales */
  873. if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
  874. return "surrogateescape";
  875. }
  876. #ifdef PY_COERCE_C_LOCALE
  877. /* surrogateescape is the default in locale coercion target locales */
  878. if (_Py_IsLocaleCoercionTarget(loc)) {
  879. return "surrogateescape";
  880. }
  881. #endif
  882. }
  883. return "strict";
  884. #else
  885. /* On Windows, always use surrogateescape by default */
  886. return "surrogateescape";
  887. #endif
  888. }
  889. static _PyInitError
  890. get_locale_encoding(char **locale_encoding)
  891. {
  892. #ifdef MS_WINDOWS
  893. char encoding[20];
  894. PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
  895. #elif defined(__ANDROID__)
  896. const char *encoding = "UTF-8";
  897. #else
  898. const char *encoding = nl_langinfo(CODESET);
  899. if (!encoding || encoding[0] == '\0') {
  900. return _Py_INIT_USER_ERR("failed to get the locale encoding: "
  901. "nl_langinfo(CODESET) failed");
  902. }
  903. #endif
  904. *locale_encoding = _PyMem_RawStrdup(encoding);
  905. if (*locale_encoding == NULL) {
  906. return _Py_INIT_NO_MEMORY();
  907. }
  908. return _Py_INIT_OK();
  909. }
  910. static _PyInitError
  911. config_init_stdio_encoding(_PyCoreConfig *config)
  912. {
  913. /* If Py_SetStandardStreamEncoding() have been called, use these
  914. parameters. */
  915. if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
  916. config->stdio_encoding = _PyMem_RawStrdup(_Py_StandardStreamEncoding);
  917. if (config->stdio_encoding == NULL) {
  918. return _Py_INIT_NO_MEMORY();
  919. }
  920. }
  921. if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
  922. config->stdio_errors = _PyMem_RawStrdup(_Py_StandardStreamErrors);
  923. if (config->stdio_errors == NULL) {
  924. return _Py_INIT_NO_MEMORY();
  925. }
  926. }
  927. if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
  928. return _Py_INIT_OK();
  929. }
  930. /* PYTHONIOENCODING environment variable */
  931. const char *opt = _PyCoreConfig_GetEnv(config, "PYTHONIOENCODING");
  932. if (opt) {
  933. char *pythonioencoding = _PyMem_RawStrdup(opt);
  934. if (pythonioencoding == NULL) {
  935. return _Py_INIT_NO_MEMORY();
  936. }
  937. char *err = strchr(pythonioencoding, ':');
  938. if (err) {
  939. *err = '\0';
  940. err++;
  941. if (!err[0]) {
  942. err = NULL;
  943. }
  944. }
  945. /* Does PYTHONIOENCODING contain an encoding? */
  946. if (pythonioencoding[0]) {
  947. if (config->stdio_encoding == NULL) {
  948. config->stdio_encoding = _PyMem_RawStrdup(pythonioencoding);
  949. if (config->stdio_encoding == NULL) {
  950. PyMem_RawFree(pythonioencoding);
  951. return _Py_INIT_NO_MEMORY();
  952. }
  953. }
  954. /* If the encoding is set but not the error handler,
  955. use "strict" error handler by default.
  956. PYTHONIOENCODING=latin1 behaves as
  957. PYTHONIOENCODING=latin1:strict. */
  958. if (!err) {
  959. err = "strict";
  960. }
  961. }
  962. if (config->stdio_errors == NULL && err != NULL) {
  963. config->stdio_errors = _PyMem_RawStrdup(err);
  964. if (config->stdio_errors == NULL) {
  965. PyMem_RawFree(pythonioencoding);
  966. return _Py_INIT_NO_MEMORY();
  967. }
  968. }
  969. PyMem_RawFree(pythonioencoding);
  970. }
  971. /* UTF-8 Mode uses UTF-8/surrogateescape */
  972. if (config->utf8_mode) {
  973. if (config->stdio_encoding == NULL) {
  974. config->stdio_encoding = _PyMem_RawStrdup("utf-8");
  975. if (config->stdio_encoding == NULL) {
  976. return _Py_INIT_NO_MEMORY();
  977. }
  978. }
  979. if (config->stdio_errors == NULL) {
  980. config->stdio_errors = _PyMem_RawStrdup("surrogateescape");
  981. if (config->stdio_errors == NULL) {
  982. return _Py_INIT_NO_MEMORY();
  983. }
  984. }
  985. }
  986. /* Choose the default error handler based on the current locale. */
  987. if (config->stdio_encoding == NULL) {
  988. _PyInitError err = get_locale_encoding(&config->stdio_encoding);
  989. if (_Py_INIT_FAILED(err)) {
  990. return err;
  991. }
  992. }
  993. if (config->stdio_errors == NULL) {
  994. const char *errors = get_stdio_errors(config);
  995. config->stdio_errors = _PyMem_RawStrdup(errors);
  996. if (config->stdio_errors == NULL) {
  997. return _Py_INIT_NO_MEMORY();
  998. }
  999. }
  1000. return _Py_INIT_OK();
  1001. }
  1002. static _PyInitError
  1003. config_init_fs_encoding(_PyCoreConfig *config)
  1004. {
  1005. #ifdef MS_WINDOWS
  1006. if (config->legacy_windows_fs_encoding) {
  1007. /* Legacy Windows filesystem encoding: mbcs/replace */
  1008. if (config->filesystem_encoding == NULL) {
  1009. config->filesystem_encoding = _PyMem_RawStrdup("mbcs");
  1010. if (config->filesystem_encoding == NULL) {
  1011. return _Py_INIT_NO_MEMORY();
  1012. }
  1013. }
  1014. if (config->filesystem_errors == NULL) {
  1015. config->filesystem_errors = _PyMem_RawStrdup("replace");
  1016. if (config->filesystem_errors == NULL) {
  1017. return _Py_INIT_NO_MEMORY();
  1018. }
  1019. }
  1020. }
  1021. /* Windows defaults to utf-8/surrogatepass (PEP 529).
  1022. Note: UTF-8 Mode takes the same code path and the Legacy Windows FS
  1023. encoding has the priortiy over UTF-8 Mode. */
  1024. if (config->filesystem_encoding == NULL) {
  1025. config->filesystem_encoding = _PyMem_RawStrdup("utf-8");
  1026. if (config->filesystem_encoding == NULL) {
  1027. return _Py_INIT_NO_MEMORY();
  1028. }
  1029. }
  1030. if (config->filesystem_errors == NULL) {
  1031. config->filesystem_errors = _PyMem_RawStrdup("surrogatepass");
  1032. if (config->filesystem_errors == NULL) {
  1033. return _Py_INIT_NO_MEMORY();
  1034. }
  1035. }
  1036. #else
  1037. if (config->filesystem_encoding == NULL) {
  1038. if (config->utf8_mode) {
  1039. /* UTF-8 Mode use: utf-8/surrogateescape */
  1040. config->filesystem_encoding = _PyMem_RawStrdup("utf-8");
  1041. /* errors defaults to surrogateescape above */
  1042. }
  1043. else if (_Py_GetForceASCII()) {
  1044. config->filesystem_encoding = _PyMem_RawStrdup("ascii");
  1045. }
  1046. else {
  1047. /* macOS and Android use UTF-8,
  1048. other platforms use the locale encoding. */
  1049. #if defined(__APPLE__) || defined(__ANDROID__)
  1050. config->filesystem_encoding = _PyMem_RawStrdup("utf-8");
  1051. #else
  1052. _PyInitError err = get_locale_encoding(&config->filesystem_encoding);
  1053. if (_Py_INIT_FAILED(err)) {
  1054. return err;
  1055. }
  1056. #endif
  1057. }
  1058. if (config->filesystem_encoding == NULL) {
  1059. return _Py_INIT_NO_MEMORY();
  1060. }
  1061. }
  1062. if (config->filesystem_errors == NULL) {
  1063. /* by default, use the "surrogateescape" error handler */
  1064. config->filesystem_errors = _PyMem_RawStrdup("surrogateescape");
  1065. if (config->filesystem_errors == NULL) {
  1066. return _Py_INIT_NO_MEMORY();
  1067. }
  1068. }
  1069. #endif
  1070. return _Py_INIT_OK();
  1071. }
  1072. /* Read configuration settings from standard locations
  1073. *
  1074. * This function doesn't make any changes to the interpreter state - it
  1075. * merely populates any missing configuration settings. This allows an
  1076. * embedding application to completely override a config option by
  1077. * setting it before calling this function, or else modify the default
  1078. * setting before passing the fully populated config to Py_EndInitialization.
  1079. *
  1080. * More advanced selective initialization tricks are possible by calling
  1081. * this function multiple times with various preconfigured settings.
  1082. */
  1083. _PyInitError
  1084. _PyCoreConfig_Read(_PyCoreConfig *config)
  1085. {
  1086. _PyInitError err;
  1087. _PyCoreConfig_GetGlobalConfig(config);
  1088. assert(config->use_environment >= 0);
  1089. if (config->isolated > 0) {
  1090. config->use_environment = 0;
  1091. config->user_site_directory = 0;
  1092. }
  1093. #ifdef MS_WINDOWS
  1094. if (config->legacy_windows_fs_encoding) {
  1095. config->utf8_mode = 0;
  1096. }
  1097. #endif
  1098. if (config->use_environment) {
  1099. err = config_read_env_vars(config);
  1100. if (_Py_INIT_FAILED(err)) {
  1101. return err;
  1102. }
  1103. }
  1104. /* -X options */
  1105. if (config_get_xoption(config, L"showrefcount")) {
  1106. config->show_ref_count = 1;
  1107. }
  1108. if (config_get_xoption(config, L"showalloccount")) {
  1109. config->show_alloc_count = 1;
  1110. }
  1111. err = config_read_complex_options(config);
  1112. if (_Py_INIT_FAILED(err)) {
  1113. return err;
  1114. }
  1115. if (config->utf8_mode < 0) {
  1116. err = config_init_utf8_mode(config);
  1117. if (_Py_INIT_FAILED(err)) {
  1118. return err;
  1119. }
  1120. }
  1121. if (config->home == NULL) {
  1122. err = config_init_home(config);
  1123. if (_Py_INIT_FAILED(err)) {
  1124. return err;
  1125. }
  1126. }
  1127. if (config->program_name == NULL) {
  1128. err = config_init_program_name(config);
  1129. if (_Py_INIT_FAILED(err)) {
  1130. return err;
  1131. }
  1132. }
  1133. if (config->utf8_mode < 0 || config->coerce_c_locale < 0) {
  1134. config_init_locale(config);
  1135. }
  1136. if (config->_install_importlib) {
  1137. err = _PyCoreConfig_InitPathConfig(config);
  1138. if (_Py_INIT_FAILED(err)) {
  1139. return err;
  1140. }
  1141. }
  1142. /* default values */
  1143. if (config->dev_mode) {
  1144. if (config->faulthandler < 0) {
  1145. config->faulthandler = 1;
  1146. }
  1147. if (config->allocator == NULL) {
  1148. config->allocator = "debug";
  1149. }
  1150. }
  1151. if (config->use_hash_seed < 0) {
  1152. config->use_hash_seed = 0;
  1153. config->hash_seed = 0;
  1154. }
  1155. if (config->faulthandler < 0) {
  1156. config->faulthandler = 0;
  1157. }
  1158. if (config->tracemalloc < 0) {
  1159. config->tracemalloc = 0;
  1160. }
  1161. if (config->coerce_c_locale < 0) {
  1162. config->coerce_c_locale = 0;
  1163. }
  1164. if (config->utf8_mode < 0) {
  1165. config->utf8_mode = 0;
  1166. }
  1167. if (config->argc < 0) {
  1168. config->argc = 0;
  1169. }
  1170. if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
  1171. err = config_init_fs_encoding(config);
  1172. if (_Py_INIT_FAILED(err)) {
  1173. return err;
  1174. }
  1175. }
  1176. err = config_init_stdio_encoding(config);
  1177. if (_Py_INIT_FAILED(err)) {
  1178. return err;
  1179. }
  1180. assert(config->coerce_c_locale >= 0);
  1181. assert(config->use_environment >= 0);
  1182. assert(config->filesystem_encoding != NULL);
  1183. assert(config->filesystem_errors != NULL);
  1184. assert(config->stdio_encoding != NULL);
  1185. assert(config->stdio_errors != NULL);
  1186. assert(config->_check_hash_pycs_mode != NULL);
  1187. return _Py_INIT_OK();
  1188. }