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.

1355 lines
38 KiB

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