| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  | #include "Python.h"
 | 
					
						
							| 
									
										
										
										
											2021-09-27 10:00:32 -06:00
										 |  |  | #include "pycore_fileutils.h"     // DECODE_LOCALE_ERR
 | 
					
						
							| 
									
										
										
										
											2020-04-15 04:01:58 +02:00
										 |  |  | #include "pycore_getopt.h"        // _PyOS_GetOpt()
 | 
					
						
							|  |  |  | #include "pycore_initconfig.h"    // _PyArgv
 | 
					
						
							| 
									
										
										
										
											2023-07-04 11:41:43 +02:00
										 |  |  | #include "pycore_pylifecycle.h"   // _Py_LegacyLocaleDetected()
 | 
					
						
							| 
									
										
										
										
											2020-04-15 02:57:50 +02:00
										 |  |  | #include "pycore_pymem.h"         // _PyMem_GetAllocatorName()
 | 
					
						
							|  |  |  | #include "pycore_runtime.h"       // _PyRuntime_Initialize()
 | 
					
						
							| 
									
										
										
										
											2021-10-13 19:25:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-15 02:57:50 +02:00
										 |  |  | #include <locale.h>               // setlocale()
 | 
					
						
							| 
									
										
										
										
											2021-10-13 19:25:53 +02:00
										 |  |  | #include <stdlib.h>               // getenv()
 | 
					
						
							| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | /* Forward declarations */ | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | preconfig_copy(PyPreConfig *config, const PyPreConfig *config2); | 
					
						
							| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --- File system encoding/errors -------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const char *Py_FileSystemDefaultEncoding = NULL; | 
					
						
							|  |  |  | int Py_HasFileSystemDefaultEncoding = 0; | 
					
						
							|  |  |  | const char *Py_FileSystemDefaultEncodeErrors = NULL; | 
					
						
							|  |  |  | int _Py_HasFileSystemDefaultEncodeErrors = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | _Py_ClearFileSystemEncoding(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-06-17 16:12:00 +02:00
										 |  |  | _Py_COMP_DIAG_PUSH | 
					
						
							|  |  |  | _Py_COMP_DIAG_IGNORE_DEPR_DECLS | 
					
						
							| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  |     if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { | 
					
						
							|  |  |  |         PyMem_RawFree((char*)Py_FileSystemDefaultEncoding); | 
					
						
							|  |  |  |         Py_FileSystemDefaultEncoding = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!_Py_HasFileSystemDefaultEncodeErrors && Py_FileSystemDefaultEncodeErrors) { | 
					
						
							|  |  |  |         PyMem_RawFree((char*)Py_FileSystemDefaultEncodeErrors); | 
					
						
							|  |  |  |         Py_FileSystemDefaultEncodeErrors = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-06-17 16:12:00 +02:00
										 |  |  | _Py_COMP_DIAG_POP | 
					
						
							| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Set Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors
 | 
					
						
							| 
									
										
										
										
											2020-11-02 16:49:54 +01:00
										 |  |  |    global configuration variables to PyConfig.filesystem_encoding and | 
					
						
							|  |  |  |    PyConfig.filesystem_errors (encoded to UTF-8). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Function called by _PyUnicode_InitEncodings(). */ | 
					
						
							| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  | int | 
					
						
							|  |  |  | _Py_SetFileSystemEncoding(const char *encoding, const char *errors) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     char *encoding2 = _PyMem_RawStrdup(encoding); | 
					
						
							|  |  |  |     if (encoding2 == NULL) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     char *errors2 = _PyMem_RawStrdup(errors); | 
					
						
							|  |  |  |     if (errors2 == NULL) { | 
					
						
							|  |  |  |         PyMem_RawFree(encoding2); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _Py_ClearFileSystemEncoding(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-17 16:12:00 +02:00
										 |  |  | _Py_COMP_DIAG_PUSH | 
					
						
							|  |  |  | _Py_COMP_DIAG_IGNORE_DEPR_DECLS | 
					
						
							| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  |     Py_FileSystemDefaultEncoding = encoding2; | 
					
						
							|  |  |  |     Py_HasFileSystemDefaultEncoding = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_FileSystemDefaultEncodeErrors = errors2; | 
					
						
							|  |  |  |     _Py_HasFileSystemDefaultEncodeErrors = 0; | 
					
						
							| 
									
										
										
										
											2022-06-17 16:12:00 +02:00
										 |  |  | _Py_COMP_DIAG_POP | 
					
						
							| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --- _PyArgv ---------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | /* Decode bytes_argv using Py_DecodeLocale() */ | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | PyStatus | 
					
						
							|  |  |  | _PyArgv_AsWstrList(const _PyArgv *args, PyWideStringList *list) | 
					
						
							| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-09-30 01:40:17 +02:00
										 |  |  |     PyWideStringList wargv = _PyWideStringList_INIT; | 
					
						
							| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  |     if (args->use_bytes_argv) { | 
					
						
							| 
									
										
										
										
											2019-03-15 15:08:05 +01:00
										 |  |  |         size_t size = sizeof(wchar_t*) * args->argc; | 
					
						
							|  |  |  |         wargv.items = (wchar_t **)PyMem_RawMalloc(size); | 
					
						
							|  |  |  |         if (wargv.items == NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |             return _PyStatus_NO_MEMORY(); | 
					
						
							| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 15:08:05 +01:00
										 |  |  |         for (Py_ssize_t i = 0; i < args->argc; i++) { | 
					
						
							| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  |             size_t len; | 
					
						
							|  |  |  |             wchar_t *arg = Py_DecodeLocale(args->bytes_argv[i], &len); | 
					
						
							|  |  |  |             if (arg == NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |                 _PyWideStringList_Clear(&wargv); | 
					
						
							| 
									
										
										
										
											2021-09-27 10:00:32 -06:00
										 |  |  |                 return DECODE_LOCALE_ERR("command line arguments", len); | 
					
						
							| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-03-15 15:08:05 +01:00
										 |  |  |             wargv.items[i] = arg; | 
					
						
							|  |  |  |             wargv.length++; | 
					
						
							| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-03-15 15:08:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         _PyWideStringList_Clear(list); | 
					
						
							| 
									
										
										
										
											2019-03-15 15:08:05 +01:00
										 |  |  |         *list = wargv; | 
					
						
							| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-03-15 15:08:05 +01:00
										 |  |  |         wargv.length = args->argc; | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |         wargv.items = (wchar_t **)args->wchar_argv; | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         if (_PyWideStringList_Copy(list, &wargv) < 0) { | 
					
						
							|  |  |  |             return _PyStatus_NO_MEMORY(); | 
					
						
							| 
									
										
										
										
											2019-03-15 15:08:05 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-03-01 17:52:56 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-05 02:44:12 +01:00
										 |  |  | /* --- _PyPreCmdline ------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-20 04:25:38 +01:00
										 |  |  | void | 
					
						
							|  |  |  | _PyPreCmdline_Clear(_PyPreCmdline *cmdline) | 
					
						
							| 
									
										
										
										
											2019-03-05 02:44:12 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     _PyWideStringList_Clear(&cmdline->argv); | 
					
						
							|  |  |  |     _PyWideStringList_Clear(&cmdline->xoptions); | 
					
						
							| 
									
										
										
										
											2019-03-05 02:44:12 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | PyStatus | 
					
						
							| 
									
										
										
										
											2019-03-25 17:54:58 +01:00
										 |  |  | _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, const _PyArgv *args) | 
					
						
							| 
									
										
										
										
											2019-03-20 04:25:38 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     return _PyArgv_AsWstrList(args, &cmdline->argv); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | precmdline_get_preconfig(_PyPreCmdline *cmdline, const PyPreConfig *config) | 
					
						
							| 
									
										
										
										
											2019-03-25 17:54:58 +01:00
										 |  |  | { | 
					
						
							|  |  |  | #define COPY_ATTR(ATTR) \
 | 
					
						
							|  |  |  |     if (config->ATTR != -1) { \ | 
					
						
							|  |  |  |         cmdline->ATTR = config->ATTR; \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     COPY_ATTR(isolated); | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     COPY_ATTR(use_environment); | 
					
						
							| 
									
										
										
										
											2019-03-26 02:31:11 +01:00
										 |  |  |     COPY_ATTR(dev_mode); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef COPY_ATTR
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | precmdline_set_preconfig(const _PyPreCmdline *cmdline, PyPreConfig *config) | 
					
						
							| 
									
										
										
										
											2019-03-26 02:31:11 +01:00
										 |  |  | { | 
					
						
							|  |  |  | #define COPY_ATTR(ATTR) \
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     config->ATTR = cmdline->ATTR | 
					
						
							| 
									
										
										
										
											2019-03-26 02:31:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     COPY_ATTR(isolated); | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     COPY_ATTR(use_environment); | 
					
						
							| 
									
										
										
										
											2019-03-26 02:31:11 +01:00
										 |  |  |     COPY_ATTR(dev_mode); | 
					
						
							| 
									
										
										
										
											2019-03-25 17:54:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #undef COPY_ATTR
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | PyStatus | 
					
						
							|  |  |  | _PyPreCmdline_SetConfig(const _PyPreCmdline *cmdline, PyConfig *config) | 
					
						
							| 
									
										
										
										
											2019-03-25 18:37:10 +01:00
										 |  |  | { | 
					
						
							|  |  |  | #define COPY_ATTR(ATTR) \
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     config->ATTR = cmdline->ATTR | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyStatus status = _PyWideStringList_Extend(&config->xoptions, &cmdline->xoptions); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-03-25 18:37:10 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     COPY_ATTR(isolated); | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     COPY_ATTR(use_environment); | 
					
						
							| 
									
										
										
										
											2019-03-26 02:31:11 +01:00
										 |  |  |     COPY_ATTR(dev_mode); | 
					
						
							| 
									
										
										
										
											2021-03-29 12:28:14 +09:00
										 |  |  |     COPY_ATTR(warn_default_encoding); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-03-25 18:37:10 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #undef COPY_ATTR
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | /* Parse the command line arguments */ | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | precmdline_parse_cmdline(_PyPreCmdline *cmdline) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     const PyWideStringList *argv = &cmdline->argv; | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     _PyOS_ResetGetOpt(); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     /* Don't log parsing errors into stderr here: PyConfig_Read()
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |        is responsible for that */ | 
					
						
							|  |  |  |     _PyOS_opterr = 0; | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |         int longindex = -1; | 
					
						
							|  |  |  |         int c = _PyOS_GetOpt(argv->length, argv->items, &longindex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (c == EOF || c == 'c' || c == 'm') { | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         switch (c) { | 
					
						
							|  |  |  |         case 'E': | 
					
						
							|  |  |  |             cmdline->use_environment = 0; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         case 'I': | 
					
						
							|  |  |  |             cmdline->isolated = 1; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         case 'X': | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |             PyStatus status = PyWideStringList_Append(&cmdline->xoptions, | 
					
						
							|  |  |  |                                                       _PyOS_optarg); | 
					
						
							|  |  |  |             if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |                 return status; | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             /* ignore other argument:
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |                handled by PyConfig_Read() */ | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } while (1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | PyStatus | 
					
						
							|  |  |  | _PyPreCmdline_Read(_PyPreCmdline *cmdline, const PyPreConfig *preconfig) | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     precmdline_get_preconfig(cmdline, preconfig); | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |     if (preconfig->parse_argv) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         PyStatus status = precmdline_parse_cmdline(cmdline); | 
					
						
							|  |  |  |         if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |             return status; | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* isolated, use_environment */ | 
					
						
							|  |  |  |     if (cmdline->isolated < 0) { | 
					
						
							|  |  |  |         cmdline->isolated = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (cmdline->isolated > 0) { | 
					
						
							|  |  |  |         cmdline->use_environment = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (cmdline->use_environment < 0) { | 
					
						
							|  |  |  |         cmdline->use_environment = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* dev_mode */ | 
					
						
							| 
									
										
										
										
											2019-05-18 03:21:27 +02:00
										 |  |  |     if ((cmdline->dev_mode < 0) | 
					
						
							|  |  |  |         && (_Py_get_xoption(&cmdline->xoptions, L"dev") | 
					
						
							|  |  |  |             || _Py_GetEnv(cmdline->use_environment, "PYTHONDEVMODE"))) | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |         cmdline->dev_mode = 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (cmdline->dev_mode < 0) { | 
					
						
							|  |  |  |         cmdline->dev_mode = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-29 12:28:14 +09:00
										 |  |  |     // warn_default_encoding
 | 
					
						
							|  |  |  |     if (_Py_get_xoption(&cmdline->xoptions, L"warn_default_encoding") | 
					
						
							|  |  |  |             || _Py_GetEnv(cmdline->use_environment, "PYTHONWARNDEFAULTENCODING")) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         cmdline->warn_default_encoding = 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     assert(cmdline->use_environment >= 0); | 
					
						
							|  |  |  |     assert(cmdline->isolated >= 0); | 
					
						
							|  |  |  |     assert(cmdline->dev_mode >= 0); | 
					
						
							| 
									
										
										
										
											2021-03-29 12:28:14 +09:00
										 |  |  |     assert(cmdline->warn_default_encoding >= 0); | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | /* --- PyPreConfig ----------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-18 03:21:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 10:56:37 +02:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | _PyPreConfig_InitCompatConfig(PyPreConfig *config) | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-18 03:21:27 +02:00
										 |  |  |     memset(config, 0, sizeof(*config)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-22 23:58:50 +02:00
										 |  |  |     config->_config_init = (int)_PyConfig_INIT_COMPAT; | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |     config->parse_argv = 0; | 
					
						
							| 
									
										
										
										
											2019-05-18 03:21:27 +02:00
										 |  |  |     config->isolated = -1; | 
					
						
							|  |  |  |     config->use_environment = -1; | 
					
						
							|  |  |  |     config->configure_locale = 1; | 
					
						
							| 
									
										
										
										
											2019-05-23 04:12:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-15 10:45:41 +01:00
										 |  |  |     /* gh-80624: C locale coercion (PEP 538) is disabled by default using
 | 
					
						
							|  |  |  |        the Compat configuration. | 
					
						
							| 
									
										
										
										
											2019-05-23 04:12:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-15 10:45:41 +01:00
										 |  |  |        Py_UTF8Mode=0 disables the UTF-8 mode. PYTHONUTF8 environment variable | 
					
						
							| 
									
										
										
										
											2019-05-23 04:12:27 +02:00
										 |  |  |        is ignored (even if use_environment=1). */ | 
					
						
							| 
									
										
										
										
											2025-07-15 10:45:41 +01:00
										 |  |  |     config->utf8_mode = 1; | 
					
						
							| 
									
										
										
										
											2019-05-23 04:12:27 +02:00
										 |  |  |     config->coerce_c_locale = 0; | 
					
						
							|  |  |  |     config->coerce_c_locale_warn = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-18 03:21:27 +02:00
										 |  |  |     config->dev_mode = -1; | 
					
						
							|  |  |  |     config->allocator = PYMEM_ALLOCATOR_NOT_SET; | 
					
						
							|  |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  |     config->legacy_windows_fs_encoding = -1; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 10:56:37 +02:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | PyPreConfig_InitPythonConfig(PyPreConfig *config) | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-01 10:56:37 +02:00
										 |  |  |     _PyPreConfig_InitCompatConfig(config); | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-22 23:58:50 +02:00
										 |  |  |     config->_config_init = (int)_PyConfig_INIT_PYTHON; | 
					
						
							|  |  |  |     config->isolated = 0; | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |     config->parse_argv = 1; | 
					
						
							| 
									
										
										
										
											2019-05-22 23:58:50 +02:00
										 |  |  |     config->use_environment = 1; | 
					
						
							| 
									
										
										
										
											2025-07-15 10:45:41 +01:00
										 |  |  |     /* Set to -1 to enable C locale coercion (PEP 538) depending on
 | 
					
						
							|  |  |  |        the LC_CTYPE locale, PYTHONUTF8 and PYTHONCOERCECLOCALE | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  |        environment variables. */ | 
					
						
							|  |  |  |     config->coerce_c_locale = -1; | 
					
						
							|  |  |  |     config->coerce_c_locale_warn = -1; | 
					
						
							|  |  |  |     config->utf8_mode = -1; | 
					
						
							| 
									
										
										
										
											2019-05-22 23:58:50 +02:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  |     config->legacy_windows_fs_encoding = 0; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 10:56:37 +02:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | PyPreConfig_InitIsolatedConfig(PyPreConfig *config) | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-01 10:56:37 +02:00
										 |  |  |     _PyPreConfig_InitCompatConfig(config); | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-22 23:58:50 +02:00
										 |  |  |     config->_config_init = (int)_PyConfig_INIT_ISOLATED; | 
					
						
							| 
									
										
										
										
											2019-05-17 22:44:16 +02:00
										 |  |  |     config->configure_locale = 0; | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  |     config->isolated = 1; | 
					
						
							|  |  |  |     config->use_environment = 0; | 
					
						
							| 
									
										
										
										
											2025-07-15 10:45:41 +01:00
										 |  |  |     config->utf8_mode = 1; | 
					
						
							| 
									
										
										
										
											2019-05-18 03:21:27 +02:00
										 |  |  |     config->dev_mode = 0; | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  |     config->legacy_windows_fs_encoding = 0; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-28 04:28:35 +02:00
										 |  |  | PyStatus | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | _PyPreConfig_InitFromPreConfig(PyPreConfig *config, | 
					
						
							|  |  |  |                                const PyPreConfig *config2) | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-01 10:56:37 +02:00
										 |  |  |     PyPreConfig_InitPythonConfig(config); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     preconfig_copy(config, config2); | 
					
						
							| 
									
										
										
										
											2019-09-28 04:28:35 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 10:56:37 +02:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | _PyPreConfig_InitFromConfig(PyPreConfig *preconfig, const PyConfig *config) | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     _PyConfigInitEnum config_init = (_PyConfigInitEnum)config->_config_init; | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |     switch (config_init) { | 
					
						
							| 
									
										
										
										
											2019-05-22 23:58:50 +02:00
										 |  |  |     case _PyConfig_INIT_PYTHON: | 
					
						
							| 
									
										
										
										
											2019-10-01 10:56:37 +02:00
										 |  |  |         PyPreConfig_InitPythonConfig(preconfig); | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2019-05-22 23:58:50 +02:00
										 |  |  |     case _PyConfig_INIT_ISOLATED: | 
					
						
							| 
									
										
										
										
											2019-10-01 10:56:37 +02:00
										 |  |  |         PyPreConfig_InitIsolatedConfig(preconfig); | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2019-05-22 23:58:50 +02:00
										 |  |  |     case _PyConfig_INIT_COMPAT: | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2019-10-01 10:56:37 +02:00
										 |  |  |         _PyPreConfig_InitCompatConfig(preconfig); | 
					
						
							| 
									
										
										
										
											2019-09-28 04:28:35 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     _PyPreConfig_GetConfig(preconfig, config); | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static void | 
					
						
							|  |  |  | preconfig_copy(PyPreConfig *config, const PyPreConfig *config2) | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  | { | 
					
						
							|  |  |  | #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-23 04:12:27 +02:00
										 |  |  |     COPY_ATTR(_config_init); | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |     COPY_ATTR(parse_argv); | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  |     COPY_ATTR(isolated); | 
					
						
							|  |  |  |     COPY_ATTR(use_environment); | 
					
						
							| 
									
										
										
										
											2019-05-17 22:44:16 +02:00
										 |  |  |     COPY_ATTR(configure_locale); | 
					
						
							| 
									
										
										
										
											2019-03-26 02:31:11 +01:00
										 |  |  |     COPY_ATTR(dev_mode); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  |     COPY_ATTR(coerce_c_locale); | 
					
						
							|  |  |  |     COPY_ATTR(coerce_c_locale_warn); | 
					
						
							| 
									
										
										
										
											2019-05-18 00:38:16 +02:00
										 |  |  |     COPY_ATTR(utf8_mode); | 
					
						
							|  |  |  |     COPY_ATTR(allocator); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  |     COPY_ATTR(legacy_windows_fs_encoding); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #undef COPY_ATTR
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | PyObject* | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | _PyPreConfig_AsDict(const PyPreConfig *config) | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     PyObject *dict; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dict = PyDict_New(); | 
					
						
							|  |  |  |     if (dict == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  | #define SET_ITEM_INT(ATTR) \
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |         do { \ | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |             PyObject *obj = PyLong_FromLong(config->ATTR); \ | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |             if (obj == NULL) { \ | 
					
						
							|  |  |  |                 goto fail; \ | 
					
						
							|  |  |  |             } \ | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |             int res = PyDict_SetItemString(dict, #ATTR, obj); \ | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |             Py_DECREF(obj); \ | 
					
						
							|  |  |  |             if (res < 0) { \ | 
					
						
							|  |  |  |                 goto fail; \ | 
					
						
							|  |  |  |             } \ | 
					
						
							|  |  |  |         } while (0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-23 04:12:27 +02:00
										 |  |  |     SET_ITEM_INT(_config_init); | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |     SET_ITEM_INT(parse_argv); | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     SET_ITEM_INT(isolated); | 
					
						
							|  |  |  |     SET_ITEM_INT(use_environment); | 
					
						
							| 
									
										
										
										
											2019-05-17 22:44:16 +02:00
										 |  |  |     SET_ITEM_INT(configure_locale); | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     SET_ITEM_INT(coerce_c_locale); | 
					
						
							|  |  |  |     SET_ITEM_INT(coerce_c_locale_warn); | 
					
						
							|  |  |  |     SET_ITEM_INT(utf8_mode); | 
					
						
							|  |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  |     SET_ITEM_INT(legacy_windows_fs_encoding); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     SET_ITEM_INT(dev_mode); | 
					
						
							| 
									
										
										
										
											2019-05-17 15:20:52 +02:00
										 |  |  |     SET_ITEM_INT(allocator); | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     return dict; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | fail: | 
					
						
							|  |  |  |     Py_DECREF(dict); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef SET_ITEM_INT
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:40:14 +01:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | _PyPreConfig_GetConfig(PyPreConfig *preconfig, const PyConfig *config) | 
					
						
							| 
									
										
										
										
											2019-03-27 13:40:14 +01:00
										 |  |  | { | 
					
						
							|  |  |  | #define COPY_ATTR(ATTR) \
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (config->ATTR != -1) { \ | 
					
						
							|  |  |  |         preconfig->ATTR = config->ATTR; \ | 
					
						
							| 
									
										
										
										
											2019-03-27 13:40:14 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |     COPY_ATTR(parse_argv); | 
					
						
							| 
									
										
										
										
											2019-03-27 13:40:14 +01:00
										 |  |  |     COPY_ATTR(isolated); | 
					
						
							|  |  |  |     COPY_ATTR(use_environment); | 
					
						
							|  |  |  |     COPY_ATTR(dev_mode); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef COPY_ATTR
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | preconfig_get_global_vars(PyPreConfig *config) | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-22 23:58:50 +02:00
										 |  |  |     if (config->_config_init != _PyConfig_INIT_COMPAT) { | 
					
						
							|  |  |  |         /* Python and Isolated configuration ignore global variables */ | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  | #define COPY_FLAG(ATTR, VALUE) \
 | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  |     if (config->ATTR < 0) { \ | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |         config->ATTR = VALUE; \ | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  | #define COPY_NOT_FLAG(ATTR, VALUE) \
 | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  |     if (config->ATTR < 0) { \ | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |         config->ATTR = !(VALUE); \ | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-17 16:12:00 +02:00
										 |  |  | _Py_COMP_DIAG_PUSH | 
					
						
							|  |  |  | _Py_COMP_DIAG_IGNORE_DEPR_DECLS | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  |     COPY_FLAG(isolated, Py_IsolatedFlag); | 
					
						
							|  |  |  |     COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); | 
					
						
							| 
									
										
										
										
											2019-05-23 04:12:27 +02:00
										 |  |  |     if (Py_UTF8Mode > 0) { | 
					
						
							|  |  |  |         config->utf8_mode = Py_UTF8Mode; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  |     COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-06-17 16:12:00 +02:00
										 |  |  | _Py_COMP_DIAG_POP | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #undef COPY_FLAG
 | 
					
						
							|  |  |  | #undef COPY_NOT_FLAG
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | preconfig_set_global_vars(const PyPreConfig *config) | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  | { | 
					
						
							|  |  |  | #define COPY_FLAG(ATTR, VAR) \
 | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  |     if (config->ATTR >= 0) { \ | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |         VAR = config->ATTR; \ | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  | #define COPY_NOT_FLAG(ATTR, VAR) \
 | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  |     if (config->ATTR >= 0) { \ | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |         VAR = !config->ATTR; \ | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-17 16:12:00 +02:00
										 |  |  | _Py_COMP_DIAG_PUSH | 
					
						
							|  |  |  | _Py_COMP_DIAG_IGNORE_DEPR_DECLS | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  |     COPY_FLAG(isolated, Py_IsolatedFlag); | 
					
						
							|  |  |  |     COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  |     COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     COPY_FLAG(utf8_mode, Py_UTF8Mode); | 
					
						
							| 
									
										
										
										
											2022-06-17 16:12:00 +02:00
										 |  |  | _Py_COMP_DIAG_POP | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #undef COPY_FLAG
 | 
					
						
							|  |  |  | #undef COPY_NOT_FLAG
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | const char* | 
					
						
							| 
									
										
										
										
											2019-03-26 00:03:15 +01:00
										 |  |  | _Py_GetEnv(int use_environment, const char *name) | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-26 00:03:15 +01:00
										 |  |  |     assert(use_environment >= 0); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 00:03:15 +01:00
										 |  |  |     if (!use_environment) { | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const char *var = getenv(name); | 
					
						
							|  |  |  |     if (var && var[0] != '\0') { | 
					
						
							|  |  |  |         return var; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | _Py_str_to_int(const char *str, int *result) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const char *endptr = str; | 
					
						
							|  |  |  |     errno = 0; | 
					
						
							|  |  |  |     long value = strtol(str, (char **)&endptr, 10); | 
					
						
							|  |  |  |     if (*endptr != '\0' || errno == ERANGE) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (value < INT_MIN || value > INT_MAX) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *result = (int)value; | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2019-03-26 00:03:15 +01:00
										 |  |  | _Py_get_env_flag(int use_environment, int *flag, const char *name) | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-26 00:03:15 +01:00
										 |  |  |     const char *var = _Py_GetEnv(use_environment, name); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  |     if (!var) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     int value; | 
					
						
							|  |  |  |     if (_Py_str_to_int(var, &value) < 0 || value < 0) { | 
					
						
							|  |  |  |         /* PYTHONDEBUG=text and PYTHONDEBUG=-2 behave as PYTHONDEBUG=1 */ | 
					
						
							|  |  |  |         value = 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (*flag < value) { | 
					
						
							|  |  |  |         *flag = value; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const wchar_t* | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | _Py_get_xoption(const PyWideStringList *xoptions, const wchar_t *name) | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-15 15:08:05 +01:00
										 |  |  |     for (Py_ssize_t i=0; i < xoptions->length; i++) { | 
					
						
							|  |  |  |         const wchar_t *option = xoptions->items[i]; | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  |         size_t len; | 
					
						
							|  |  |  |         wchar_t *sep = wcschr(option, L'='); | 
					
						
							|  |  |  |         if (sep != NULL) { | 
					
						
							|  |  |  |             len = (sep - option); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |             len = wcslen(option); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (wcsncmp(option, name, len) == 0 && name[len] == L'\0') { | 
					
						
							|  |  |  |             return option; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							|  |  |  | preconfig_init_utf8_mode(PyPreConfig *config, const _PyPreCmdline *cmdline) | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  |     if (config->legacy_windows_fs_encoding) { | 
					
						
							|  |  |  |         config->utf8_mode = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (config->utf8_mode >= 0) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  |     const wchar_t *xopt; | 
					
						
							| 
									
										
										
										
											2019-05-22 23:58:50 +02:00
										 |  |  |     xopt = _Py_get_xoption(&cmdline->xoptions, L"utf8"); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  |     if (xopt) { | 
					
						
							|  |  |  |         wchar_t *sep = wcschr(xopt, L'='); | 
					
						
							|  |  |  |         if (sep) { | 
					
						
							|  |  |  |             xopt = sep + 1; | 
					
						
							|  |  |  |             if (wcscmp(xopt, L"1") == 0) { | 
					
						
							|  |  |  |                 config->utf8_mode = 1; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else if (wcscmp(xopt, L"0") == 0) { | 
					
						
							|  |  |  |                 config->utf8_mode = 0; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |                 return _PyStatus_ERR("invalid -X utf8 option value"); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |             config->utf8_mode = 1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     const char *opt = _Py_GetEnv(config->use_environment, "PYTHONUTF8"); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  |     if (opt) { | 
					
						
							|  |  |  |         if (strcmp(opt, "1") == 0) { | 
					
						
							|  |  |  |             config->utf8_mode = 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (strcmp(opt, "0") == 0) { | 
					
						
							|  |  |  |             config->utf8_mode = 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |             return _PyStatus_ERR("invalid PYTHONUTF8 environment " | 
					
						
							| 
									
										
										
										
											2019-05-01 05:35:33 +02:00
										 |  |  |                                 "variable value"); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-15 10:45:41 +01:00
										 |  |  |     config->utf8_mode = 1; | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | preconfig_init_coerce_c_locale(PyPreConfig *config) | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-17 22:44:16 +02:00
										 |  |  |     if (!config->configure_locale) { | 
					
						
							|  |  |  |         config->coerce_c_locale = 0; | 
					
						
							|  |  |  |         config->coerce_c_locale_warn = 0; | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     const char *env = _Py_GetEnv(config->use_environment, "PYTHONCOERCECLOCALE"); | 
					
						
							|  |  |  |     if (env) { | 
					
						
							|  |  |  |         if (strcmp(env, "0") == 0) { | 
					
						
							|  |  |  |             if (config->coerce_c_locale < 0) { | 
					
						
							|  |  |  |                 config->coerce_c_locale = 0; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (strcmp(env, "warn") == 0) { | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  |             if (config->coerce_c_locale_warn < 0) { | 
					
						
							|  |  |  |                 config->coerce_c_locale_warn = 1; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |             if (config->coerce_c_locale < 0) { | 
					
						
							|  |  |  |                 config->coerce_c_locale = 1; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-03-05 17:37:44 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     /* Test if coerce_c_locale equals to -1 or equals to 1:
 | 
					
						
							|  |  |  |        PYTHONCOERCECLOCALE=1 doesn't imply that the C locale is always coerced. | 
					
						
							| 
									
										
										
										
											2025-07-12 02:18:47 +08:00
										 |  |  |        It is only coerced if the LC_CTYPE locale is "C". */ | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  |     if (config->coerce_c_locale < 0 || config->coerce_c_locale == 1) { | 
					
						
							|  |  |  |         /* The C locale enables the C locale coercion (PEP 538) */ | 
					
						
							| 
									
										
										
										
											2019-05-20 17:16:38 +02:00
										 |  |  |         if (_Py_LegacyLocaleDetected(0)) { | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  |             config->coerce_c_locale = 2; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |             config->coerce_c_locale = 0; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  |     if (config->coerce_c_locale_warn < 0) { | 
					
						
							|  |  |  |         config->coerce_c_locale_warn = 0; | 
					
						
							| 
									
										
										
										
											2019-03-05 17:37:44 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							|  |  |  | preconfig_init_allocator(PyPreConfig *config) | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-17 15:20:52 +02:00
										 |  |  |     if (config->allocator == PYMEM_ALLOCATOR_NOT_SET) { | 
					
						
							| 
									
										
										
										
											2019-03-06 12:51:53 +01:00
										 |  |  |         /* bpo-34247. The PYTHONMALLOC environment variable has the priority
 | 
					
						
							|  |  |  |            over PYTHONDEV env var and "-X dev" command line option. | 
					
						
							|  |  |  |            For example, PYTHONMALLOC=malloc PYTHONDEVMODE=1 sets the memory | 
					
						
							|  |  |  |            allocators to "malloc" (and not to "debug"). */ | 
					
						
							| 
									
										
										
										
											2019-05-17 15:20:52 +02:00
										 |  |  |         const char *envvar = _Py_GetEnv(config->use_environment, "PYTHONMALLOC"); | 
					
						
							|  |  |  |         if (envvar) { | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |             PyMemAllocatorName name; | 
					
						
							|  |  |  |             if (_PyMem_GetAllocatorName(envvar, &name) < 0) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |                 return _PyStatus_ERR("PYTHONMALLOC: unknown allocator"); | 
					
						
							| 
									
										
										
										
											2019-03-05 17:37:44 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |             config->allocator = (int)name; | 
					
						
							| 
									
										
										
										
											2019-03-05 17:37:44 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-17 15:20:52 +02:00
										 |  |  |     if (config->dev_mode && config->allocator == PYMEM_ALLOCATOR_NOT_SET) { | 
					
						
							|  |  |  |         config->allocator = PYMEM_ALLOCATOR_DEBUG; | 
					
						
							| 
									
										
										
										
											2019-03-06 12:51:53 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							|  |  |  | preconfig_read(PyPreConfig *config, _PyPreCmdline *cmdline) | 
					
						
							| 
									
										
										
										
											2019-03-06 01:44:31 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyStatus status; | 
					
						
							| 
									
										
										
										
											2019-03-06 01:44:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = _PyPreCmdline_Read(cmdline, config); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-03-06 01:44:31 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     precmdline_set_preconfig(cmdline, config); | 
					
						
							| 
									
										
										
										
											2019-03-06 01:44:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     /* legacy_windows_fs_encoding, coerce_c_locale, utf8_mode */ | 
					
						
							|  |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  |     _Py_get_env_flag(config->use_environment, | 
					
						
							|  |  |  |                      &config->legacy_windows_fs_encoding, | 
					
						
							|  |  |  |                      "PYTHONLEGACYWINDOWSFSENCODING"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-03-06 01:44:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     preconfig_init_coerce_c_locale(config); | 
					
						
							| 
									
										
										
										
											2019-03-25 23:19:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = preconfig_init_utf8_mode(config, cmdline); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-03-25 23:19:57 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     /* allocator */ | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = preconfig_init_allocator(config); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-05 02:01:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     assert(config->coerce_c_locale >= 0); | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  |     assert(config->coerce_c_locale_warn >= 0); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     assert(config->legacy_windows_fs_encoding >= 0); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     assert(config->utf8_mode >= 0); | 
					
						
							|  |  |  |     assert(config->isolated >= 0); | 
					
						
							|  |  |  |     assert(config->use_environment >= 0); | 
					
						
							|  |  |  |     assert(config->dev_mode >= 0); | 
					
						
							| 
									
										
										
										
											2019-03-05 02:44:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-03-05 02:44:12 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-25 17:54:58 +01:00
										 |  |  | /* Read the configuration from:
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |    - command line arguments | 
					
						
							| 
									
										
										
										
											2019-03-25 17:54:58 +01:00
										 |  |  |    - environment variables | 
					
						
							|  |  |  |    - Py_xxx global configuration variables | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |    - the LC_CTYPE locale */ | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | PyStatus | 
					
						
							|  |  |  | _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args) | 
					
						
							| 
									
										
										
										
											2019-03-05 02:44:12 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyStatus status; | 
					
						
							| 
									
										
										
										
											2019-03-05 02:44:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = _PyRuntime_Initialize(); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-03-05 02:44:12 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     preconfig_get_global_vars(config); | 
					
						
							| 
									
										
										
										
											2019-03-25 18:37:10 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     /* Copy LC_CTYPE locale, since it's modified later */ | 
					
						
							|  |  |  |     const char *loc = setlocale(LC_CTYPE, NULL); | 
					
						
							|  |  |  |     if (loc == NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_ERR("failed to LC_CTYPE locale"); | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     char *init_ctype_locale = _PyMem_RawStrdup(loc); | 
					
						
							|  |  |  |     if (init_ctype_locale == NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_NO_MEMORY(); | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-20 04:25:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     /* Save the config to be able to restore it if encodings change */ | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyPreConfig save_config; | 
					
						
							| 
									
										
										
										
											2019-09-28 04:28:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     status = _PyPreConfig_InitFromPreConfig(&save_config, config); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-25 18:37:10 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     /* Set LC_CTYPE to the user preferred locale */ | 
					
						
							| 
									
										
										
										
											2019-05-17 22:44:16 +02:00
										 |  |  |     if (config->configure_locale) { | 
					
						
							|  |  |  |         _Py_SetLocaleFromEnv(LC_CTYPE); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-25 00:09:48 +02:00
										 |  |  |     PyPreConfig save_runtime_config; | 
					
						
							|  |  |  |     preconfig_copy(&save_runtime_config, &_PyRuntime.preconfig); | 
					
						
							| 
									
										
										
										
											2019-04-05 11:44:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-25 00:09:48 +02:00
										 |  |  |     _PyPreCmdline cmdline = _PyPreCmdline_INIT; | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  |     int locale_coerced = 0; | 
					
						
							|  |  |  |     int loops = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while (1) { | 
					
						
							|  |  |  |         int utf8_mode = config->utf8_mode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Watchdog to prevent an infinite loop */ | 
					
						
							|  |  |  |         loops++; | 
					
						
							|  |  |  |         if (loops == 3) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |             status = _PyStatus_ERR("Encoding changed twice while " | 
					
						
							| 
									
										
										
										
											2020-06-10 19:33:11 +02:00
										 |  |  |                                    "reading the configuration"); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  |             goto done; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* bpo-34207: Py_DecodeLocale() and Py_EncodeLocale() depend
 | 
					
						
							| 
									
										
										
										
											2022-05-25 00:09:48 +02:00
										 |  |  |            on the utf8_mode and legacy_windows_fs_encoding members | 
					
						
							|  |  |  |            of _PyRuntime.preconfig. */ | 
					
						
							|  |  |  |         preconfig_copy(&_PyRuntime.preconfig, config); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-10 19:33:11 +02:00
										 |  |  |         if (args) { | 
					
						
							|  |  |  |             // Set command line arguments at each iteration. If they are bytes
 | 
					
						
							|  |  |  |             // strings, they are decoded from the new encoding.
 | 
					
						
							|  |  |  |             status = _PyPreCmdline_SetArgv(&cmdline, args); | 
					
						
							|  |  |  |             if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |                 goto done; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         status = preconfig_read(config, &cmdline); | 
					
						
							|  |  |  |         if (_PyStatus_EXCEPTION(status)) { | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  |             goto done; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* The legacy C locale assumes ASCII as the default text encoding, which
 | 
					
						
							|  |  |  |          * causes problems not only for the CPython runtime, but also other | 
					
						
							|  |  |  |          * components like GNU readline. | 
					
						
							|  |  |  |          * | 
					
						
							|  |  |  |          * Accordingly, when the CLI detects it, it attempts to coerce it to a | 
					
						
							|  |  |  |          * more capable UTF-8 based alternative. | 
					
						
							|  |  |  |          * | 
					
						
							|  |  |  |          * See the documentation of the PYTHONCOERCECLOCALE setting for more | 
					
						
							|  |  |  |          * details. | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         int encoding_changed = 0; | 
					
						
							|  |  |  |         if (config->coerce_c_locale && !locale_coerced) { | 
					
						
							|  |  |  |             locale_coerced = 1; | 
					
						
							|  |  |  |             _Py_CoerceLegacyLocale(0); | 
					
						
							|  |  |  |             encoding_changed = 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (utf8_mode == -1) { | 
					
						
							|  |  |  |             if (config->utf8_mode == 1) { | 
					
						
							|  |  |  |                 /* UTF-8 Mode enabled */ | 
					
						
							|  |  |  |                 encoding_changed = 1; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |             if (config->utf8_mode != utf8_mode) { | 
					
						
							|  |  |  |                 encoding_changed = 1; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!encoding_changed) { | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Reset the configuration before reading again the configuration,
 | 
					
						
							| 
									
										
										
										
											2020-06-10 19:33:11 +02:00
										 |  |  |            just keep UTF-8 Mode and coerce C locale value. */ | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  |         int new_utf8_mode = config->utf8_mode; | 
					
						
							|  |  |  |         int new_coerce_c_locale = config->coerce_c_locale; | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         preconfig_copy(config, &save_config); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  |         config->utf8_mode = new_utf8_mode; | 
					
						
							|  |  |  |         config->coerce_c_locale = new_coerce_c_locale; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* The encoding changed: read again the configuration
 | 
					
						
							|  |  |  |            with the new encoding */ | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | done: | 
					
						
							| 
									
										
										
										
											2022-05-25 00:09:48 +02:00
										 |  |  |     // Revert side effects
 | 
					
						
							|  |  |  |     setlocale(LC_CTYPE, init_ctype_locale); | 
					
						
							|  |  |  |     PyMem_RawFree(init_ctype_locale); | 
					
						
							|  |  |  |     preconfig_copy(&_PyRuntime.preconfig, &save_runtime_config); | 
					
						
							| 
									
										
										
										
											2019-03-26 16:58:50 +01:00
										 |  |  |     _PyPreCmdline_Clear(&cmdline); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return status; | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-06 01:44:31 +01:00
										 |  |  | /* Write the pre-configuration:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    - set the memory allocators | 
					
						
							|  |  |  |    - set Py_xxx global configuration variables | 
					
						
							|  |  |  |    - set the LC_CTYPE locale (coerce C locale, PEP 538) and set the UTF-8 mode | 
					
						
							|  |  |  |      (PEP 540) | 
					
						
							| 
									
										
										
										
											2019-03-06 01:13:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 17:16:38 +02:00
										 |  |  |    The applied configuration is written into _PyRuntime.preconfig. | 
					
						
							|  |  |  |    If the C locale cannot be coerced, set coerce_c_locale to 0. | 
					
						
							| 
									
										
										
										
											2019-03-06 01:44:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |    Do nothing if called after Py_Initialize(): ignore the new | 
					
						
							|  |  |  |    pre-configuration. */ | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | PyStatus | 
					
						
							|  |  |  | _PyPreConfig_Write(const PyPreConfig *src_config) | 
					
						
							| 
									
										
										
										
											2019-03-05 02:44:12 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyPreConfig config; | 
					
						
							| 
									
										
										
										
											2019-09-28 04:28:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     PyStatus status = _PyPreConfig_InitFromPreConfig(&config, src_config); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-20 17:16:38 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-06 00:36:56 +01:00
										 |  |  |     if (_PyRuntime.core_initialized) { | 
					
						
							| 
									
										
										
										
											2019-03-06 01:44:31 +01:00
										 |  |  |         /* bpo-34008: Calling this functions after Py_Initialize() ignores
 | 
					
						
							| 
									
										
										
										
											2019-03-06 00:36:56 +01:00
										 |  |  |            the new configuration. */ | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-03-06 00:36:56 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 17:16:38 +02:00
										 |  |  |     PyMemAllocatorName name = (PyMemAllocatorName)config.allocator; | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |     if (name != PYMEM_ALLOCATOR_NOT_SET) { | 
					
						
							|  |  |  |         if (_PyMem_SetupAllocators(name) < 0) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |             return _PyStatus_ERR("Unknown PYTHONMALLOC allocator"); | 
					
						
							| 
									
										
										
										
											2019-03-06 00:36:56 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     preconfig_set_global_vars(&config); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 17:16:38 +02:00
										 |  |  |     if (config.configure_locale) { | 
					
						
							|  |  |  |         if (config.coerce_c_locale) { | 
					
						
							|  |  |  |             if (!_Py_CoerceLegacyLocale(config.coerce_c_locale_warn)) { | 
					
						
							|  |  |  |                 /* C locale not coerced */ | 
					
						
							|  |  |  |                 config.coerce_c_locale = 0; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-05-17 22:44:16 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-03-05 12:32:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-17 22:44:16 +02:00
										 |  |  |         /* Set LC_CTYPE to the user preferred locale */ | 
					
						
							|  |  |  |         _Py_SetLocaleFromEnv(LC_CTYPE); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-06 00:36:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-23 12:05:43 +01:00
										 |  |  |     /* Write the new pre-configuration into _PyRuntime */ | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     preconfig_copy(&_PyRuntime.preconfig, &config); | 
					
						
							| 
									
										
										
										
											2019-03-23 12:05:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-03-05 02:44:12 +01:00
										 |  |  | } |