| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | /* Python interpreter top-level routines, including init/exit */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Python.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-28 01:34:37 +02:00
										 |  |  | #include "pycore_call.h"          // _PyObject_CallMethod()
 | 
					
						
							| 
									
										
										
										
											2020-04-15 04:01:58 +02:00
										 |  |  | #include "pycore_ceval.h"         // _PyEval_FiniGIL()
 | 
					
						
							| 
									
										
										
										
											2023-06-30 11:34:01 +02:00
										 |  |  | #include "pycore_codecs.h"        // _PyCodec_Lookup()
 | 
					
						
							| 
									
										
										
										
											2020-04-15 04:01:58 +02:00
										 |  |  | #include "pycore_context.h"       // _PyContext_Init()
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  | #include "pycore_dict.h"          // _PyDict_Fini()
 | 
					
						
							| 
									
										
										
										
											2023-06-28 01:34:37 +02:00
										 |  |  | #include "pycore_exceptions.h"    // _PyExc_InitTypes()
 | 
					
						
							| 
									
										
										
										
											2020-04-15 04:01:58 +02:00
										 |  |  | #include "pycore_fileutils.h"     // _Py_ResetForceASCII()
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  | #include "pycore_floatobject.h"   // _PyFloat_InitTypes()
 | 
					
						
							|  |  |  | #include "pycore_genobject.h"     // _PyAsyncGen_Fini()
 | 
					
						
							| 
									
										
										
										
											2022-11-08 10:03:03 -07:00
										 |  |  | #include "pycore_global_objects_fini_generated.h"  // "_PyStaticObjects_CheckRefcnt()
 | 
					
						
							| 
									
										
										
										
											2020-11-18 23:18:29 +01:00
										 |  |  | #include "pycore_import.h"        // _PyImport_BootstrapImp()
 | 
					
						
							| 
									
										
										
										
											2020-04-15 04:01:58 +02:00
										 |  |  | #include "pycore_initconfig.h"    // _PyStatus_OK()
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  | #include "pycore_list.h"          // _PyList_Fini()
 | 
					
						
							|  |  |  | #include "pycore_long.h"          // _PyLong_InitTypes()
 | 
					
						
							| 
									
										
										
										
											2020-04-15 04:01:58 +02:00
										 |  |  | #include "pycore_object.h"        // _PyDebug_PrintTotalRefs()
 | 
					
						
							| 
									
										
										
										
											2023-09-06 15:56:08 +02:00
										 |  |  | #include "pycore_pathconfig.h"    // _PyPathConfig_UpdateGlobal()
 | 
					
						
							| 
									
										
										
										
											2020-04-15 04:01:58 +02:00
										 |  |  | #include "pycore_pyerrors.h"      // _PyErr_Occurred()
 | 
					
						
							|  |  |  | #include "pycore_pylifecycle.h"   // _PyErr_Print()
 | 
					
						
							| 
									
										
										
										
											2022-01-27 21:23:22 +01:00
										 |  |  | #include "pycore_pymem.h"         // _PyObject_DebugMallocStats()
 | 
					
						
							| 
									
										
										
										
											2020-04-14 17:52:15 +02:00
										 |  |  | #include "pycore_pystate.h"       // _PyThreadState_GET()
 | 
					
						
							| 
									
										
										
										
											2022-02-08 13:39:07 -07:00
										 |  |  | #include "pycore_runtime.h"       // _Py_ID()
 | 
					
						
							| 
									
										
										
										
											2022-01-13 15:54:36 -07:00
										 |  |  | #include "pycore_runtime_init.h"  // _PyRuntimeState_INIT
 | 
					
						
							| 
									
										
										
										
											2023-07-22 17:04:34 +02:00
										 |  |  | #include "pycore_setobject.h"     // _PySet_NextEntry()
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  | #include "pycore_sliceobject.h"   // _PySlice_Fini()
 | 
					
						
							| 
									
										
										
										
											2020-04-15 04:01:58 +02:00
										 |  |  | #include "pycore_sysmodule.h"     // _PySys_ClearAuditHooks()
 | 
					
						
							|  |  |  | #include "pycore_traceback.h"     // _Py_DumpTracebackThreads()
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  | #include "pycore_typeobject.h"    // _PyTypes_InitTypes()
 | 
					
						
							| 
									
										
										
										
											2023-05-15 20:36:23 -07:00
										 |  |  | #include "pycore_typevarobject.h" // _Py_clear_generic_types()
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  | #include "pycore_unicodeobject.h" // _PyUnicode_InitTypes()
 | 
					
						
							| 
									
										
										
										
											2023-06-21 21:50:20 +02:00
										 |  |  | #include "pycore_weakref.h"       // _PyWeakref_GET_REF()
 | 
					
						
							| 
									
										
										
										
											2024-02-02 12:14:34 +00:00
										 |  |  | #include "cpython/optimizer.h"    // _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS
 | 
					
						
							| 
									
										
										
										
											2024-01-26 19:38:14 -08:00
										 |  |  | #include "pycore_obmalloc.h"      // _PyMem_init_obmalloc()
 | 
					
						
							| 
									
										
										
										
											2023-09-06 15:56:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-10 04:34:57 -08:00
										 |  |  | #include "opcode.h"
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-15 04:01:58 +02:00
										 |  |  | #include <locale.h>               // setlocale()
 | 
					
						
							| 
									
										
										
										
											2021-10-13 19:25:53 +02:00
										 |  |  | #include <stdlib.h>               // getenv()
 | 
					
						
							| 
									
										
										
										
											2023-09-30 22:06:45 +02:00
										 |  |  | #ifdef HAVE_UNISTD_H
 | 
					
						
							|  |  |  | #  include <unistd.h>             // isatty()
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 16:37:29 -07:00
										 |  |  | #if defined(__APPLE__)
 | 
					
						
							| 
									
										
										
										
											2023-09-06 15:56:08 +02:00
										 |  |  | #  include <mach-o/loader.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-03 16:37:29 -07:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-15 04:01:58 +02:00
										 |  |  | #ifdef HAVE_SIGNAL_H
 | 
					
						
							|  |  |  | #  include <signal.h>             // SIG_IGN
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_LANGINFO_H
 | 
					
						
							| 
									
										
										
										
											2020-04-15 04:01:58 +02:00
										 |  |  | #  include <langinfo.h>           // nl_langinfo(CODESET)
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-28 20:40:27 +02:00
										 |  |  | #ifdef HAVE_FCNTL_H
 | 
					
						
							|  |  |  | #  include <fcntl.h>              // F_GETFD
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							| 
									
										
										
										
											2020-04-15 04:01:58 +02:00
										 |  |  | #  undef BYTE
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-22 16:28:20 +02:00
										 |  |  | #define PUTS(fd, str) (void)_Py_write_noraise(fd, str, (int)strlen(str))
 | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  | /* Forward declarations */ | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus add_main_module(PyInterpreterState *interp); | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  | static PyStatus init_import_site(void); | 
					
						
							| 
									
										
										
										
											2020-03-12 02:49:05 -05:00
										 |  |  | static PyStatus init_set_builtins_open(void); | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  | static PyStatus init_sys_streams(PyThreadState *tstate); | 
					
						
							|  |  |  | static void wait_for_thread_shutdown(PyThreadState *tstate); | 
					
						
							| 
									
										
										
										
											2019-04-24 17:24:01 +02:00
										 |  |  | static void call_ll_exitfuncs(_PyRuntimeState *runtime); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 16:37:29 -07:00
										 |  |  | /* The following places the `_PyRuntime` structure in a location that can be
 | 
					
						
							|  |  |  |  * found without any external information. This is meant to ease access to the | 
					
						
							|  |  |  |  * interpreter state for various runtime debugging tools, but is *not* an | 
					
						
							|  |  |  |  * officially supported feature */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-21 10:50:20 +01:00
										 |  |  | /* Suppress deprecation warning for PyBytesObject.ob_shash */ | 
					
						
							|  |  |  | _Py_COMP_DIAG_PUSH | 
					
						
							|  |  |  | _Py_COMP_DIAG_IGNORE_DEPR_DECLS | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 16:37:29 -07:00
										 |  |  | #if defined(MS_WINDOWS)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma section("PyRuntime", read, write)
 | 
					
						
							|  |  |  | __declspec(allocate("PyRuntime")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #elif defined(__APPLE__)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | __attribute__(( | 
					
						
							|  |  |  |     section(SEG_DATA ",PyRuntime") | 
					
						
							|  |  |  | )) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _PyRuntimeState _PyRuntime | 
					
						
							|  |  |  | #if defined(__linux__) && (defined(__GNUC__) || defined(__clang__))
 | 
					
						
							|  |  |  | __attribute__ ((section (".PyRuntime"))) | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-11-11 16:30:46 -07:00
										 |  |  | = _PyRuntimeState_INIT(_PyRuntime); | 
					
						
							| 
									
										
										
										
											2022-03-30 09:35:15 +03:00
										 |  |  | _Py_COMP_DIAG_POP | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-20 00:03:01 +01:00
										 |  |  | static int runtime_initialized = 0; | 
					
						
							| 
									
										
										
										
											2017-09-07 23:51:28 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | PyStatus | 
					
						
							| 
									
										
										
										
											2017-09-07 23:51:28 -06:00
										 |  |  | _PyRuntime_Initialize(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* XXX We only initialize once in the process, which aligns with
 | 
					
						
							|  |  |  |        the static initialization of the former globals now found in | 
					
						
							|  |  |  |        _PyRuntime.  However, _PyRuntime *should* be initialized with | 
					
						
							|  |  |  |        every Py_Initialize() call, but doing so breaks the runtime. | 
					
						
							|  |  |  |        This is because the runtime state is not properly finalized | 
					
						
							|  |  |  |        currently. */ | 
					
						
							| 
									
										
										
										
											2019-03-20 00:03:01 +01:00
										 |  |  |     if (runtime_initialized) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-20 00:03:01 +01:00
										 |  |  |     runtime_initialized = 1; | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return _PyRuntimeState_Init(&_PyRuntime); | 
					
						
							| 
									
										
										
										
											2017-09-07 23:51:28 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | _PyRuntime_Finalize(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _PyRuntimeState_Fini(&_PyRuntime); | 
					
						
							| 
									
										
										
										
											2019-03-20 00:03:01 +01:00
										 |  |  |     runtime_initialized = 0; | 
					
						
							| 
									
										
										
										
											2017-09-07 23:51:28 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2023-08-18 12:34:41 +02:00
										 |  |  | Py_IsFinalizing(void) | 
					
						
							| 
									
										
										
										
											2017-09-07 23:51:28 -06:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-03-07 00:24:23 +01:00
										 |  |  |     return _PyRuntimeState_GetFinalizing(&_PyRuntime) != NULL; | 
					
						
							| 
									
										
										
										
											2017-09-07 23:51:28 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | /* Hack to force loading of object files */ | 
					
						
							|  |  |  | int (*_PyOS_mystrnicmp_hack)(const char *, const char *, Py_ssize_t) = \ | 
					
						
							|  |  |  |     PyOS_mystrnicmp; /* Python/pystrcmp.o */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-23 23:00:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-23 21:46:51 -07:00
										 |  |  | /* APIs to access the initialization flags
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Can be called prior to Py_Initialize. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-23 21:46:51 -07:00
										 |  |  | int | 
					
						
							|  |  |  | _Py_IsCoreInitialized(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-07 23:51:28 -06:00
										 |  |  |     return _PyRuntime.core_initialized; | 
					
						
							| 
									
										
										
										
											2017-05-23 21:46:51 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | Py_IsInitialized(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-07 23:51:28 -06:00
										 |  |  |     return _PyRuntime.initialized; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Helper functions to better handle the legacy C locale
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 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 as follows: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     if (_Py_LegacyLocaleDetected()) { | 
					
						
							|  |  |  |  *         _Py_CoerceLegacyLocale(); | 
					
						
							|  |  |  |  *     } | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * See the documentation of the PYTHONCOERCECLOCALE setting for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Locale coercion also impacts the default error handler for the standard | 
					
						
							|  |  |  |  * streams: while the usual default is "strict", the default for the legacy | 
					
						
							|  |  |  |  * C locale and for any of the coercion target locales is "surrogateescape". | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2019-05-20 17:16:38 +02:00
										 |  |  | _Py_LegacyLocaleDetected(int warn) | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  | { | 
					
						
							|  |  |  | #ifndef MS_WINDOWS
 | 
					
						
							| 
									
										
										
										
											2019-05-20 17:16:38 +02:00
										 |  |  |     if (!warn) { | 
					
						
							|  |  |  |         const char *locale_override = getenv("LC_ALL"); | 
					
						
							|  |  |  |         if (locale_override != NULL && *locale_override != '\0') { | 
					
						
							|  |  |  |             /* Don't coerce C locale if the LC_ALL environment variable
 | 
					
						
							|  |  |  |                is set */ | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  |     /* On non-Windows systems, the C locale is considered a legacy locale */ | 
					
						
							| 
									
										
										
										
											2017-06-18 12:29:42 +10:00
										 |  |  |     /* XXX (ncoghlan): some platforms (notably Mac OS X) don't appear to treat
 | 
					
						
							|  |  |  |      *                 the POSIX locale as a simple alias for the C locale, so | 
					
						
							|  |  |  |      *                 we may also want to check for that explicitly. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  |     const char *ctype_loc = setlocale(LC_CTYPE, NULL); | 
					
						
							|  |  |  |     return ctype_loc != NULL && strcmp(ctype_loc, "C") == 0; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     /* Windows uses code pages instead of locales, so no locale is legacy */ | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  | #ifndef MS_WINDOWS
 | 
					
						
							| 
									
										
										
										
											2017-06-18 12:29:42 +10:00
										 |  |  | static const char *_C_LOCALE_WARNING = | 
					
						
							|  |  |  |     "Python runtime initialized with LC_CTYPE=C (a locale with default ASCII " | 
					
						
							|  |  |  |     "encoding), which may cause Unicode compatibility problems. Using C.UTF-8, " | 
					
						
							|  |  |  |     "C.utf8, or UTF-8 (if available) as alternative Unicode-compatible " | 
					
						
							|  |  |  |     "locales is recommended.\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2019-04-24 18:23:53 +02:00
										 |  |  | emit_stderr_warning_for_legacy_locale(_PyRuntimeState *runtime) | 
					
						
							| 
									
										
										
										
											2017-06-18 12:29:42 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     const PyPreConfig *preconfig = &runtime->preconfig; | 
					
						
							| 
									
										
										
										
											2019-05-20 17:16:38 +02:00
										 |  |  |     if (preconfig->coerce_c_locale_warn && _Py_LegacyLocaleDetected(1)) { | 
					
						
							| 
									
										
										
										
											2018-08-29 22:56:06 +02:00
										 |  |  |         PySys_FormatStderr("%s", _C_LOCALE_WARNING); | 
					
						
							| 
									
										
										
										
											2017-06-18 12:29:42 +10:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  | #endif   /* !defined(MS_WINDOWS) */
 | 
					
						
							| 
									
										
										
										
											2017-06-18 12:29:42 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  | typedef struct _CandidateLocale { | 
					
						
							|  |  |  |     const char *locale_name; /* The locale to try as a coercion target */ | 
					
						
							|  |  |  | } _LocaleCoercionTarget; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static _LocaleCoercionTarget _TARGET_LOCALES[] = { | 
					
						
							|  |  |  |     {"C.UTF-8"}, | 
					
						
							|  |  |  |     {"C.utf8"}, | 
					
						
							| 
									
										
										
										
											2017-06-30 00:48:14 +10:00
										 |  |  |     {"UTF-8"}, | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  |     {NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-29 11:47:29 +02:00
										 |  |  | int | 
					
						
							|  |  |  | _Py_IsLocaleCoercionTarget(const char *ctype_loc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const _LocaleCoercionTarget *target = NULL; | 
					
						
							|  |  |  |     for (target = _TARGET_LOCALES; target->locale_name; target++) { | 
					
						
							|  |  |  |         if (strcmp(ctype_loc, target->locale_name) == 0) { | 
					
						
							|  |  |  |             return 1; | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-08-29 01:29:06 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-08-29 11:47:29 +02:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-29 11:47:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  | #ifdef PY_COERCE_C_LOCALE
 | 
					
						
							| 
									
										
										
										
											2017-12-16 04:54:22 +01:00
										 |  |  | static const char C_LOCALE_COERCION_WARNING[] = | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  |     "Python detected LC_CTYPE=C: LC_CTYPE coerced to %.20s (set another locale " | 
					
						
							|  |  |  |     "or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior).\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 17:16:38 +02:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2018-08-29 13:25:36 +02:00
										 |  |  | _coerce_default_locale_settings(int warn, const _LocaleCoercionTarget *target) | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  | { | 
					
						
							|  |  |  |     const char *newloc = target->locale_name; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Reset locale back to currently configured defaults */ | 
					
						
							| 
									
										
										
										
											2017-11-12 12:45:59 +01:00
										 |  |  |     _Py_SetLocaleFromEnv(LC_ALL); | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Set the relevant locale environment variable */ | 
					
						
							|  |  |  |     if (setenv("LC_CTYPE", newloc, 1)) { | 
					
						
							|  |  |  |         fprintf(stderr, | 
					
						
							|  |  |  |                 "Error setting LC_CTYPE, skipping C locale coercion\n"); | 
					
						
							| 
									
										
										
										
											2019-05-20 17:16:38 +02:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-08-29 13:25:36 +02:00
										 |  |  |     if (warn) { | 
					
						
							| 
									
										
										
										
											2017-12-16 04:54:22 +01:00
										 |  |  |         fprintf(stderr, C_LOCALE_COERCION_WARNING, newloc); | 
					
						
							| 
									
										
										
										
											2017-06-18 12:29:42 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Reconfigure with the overridden environment variables */ | 
					
						
							| 
									
										
										
										
											2017-11-12 12:45:59 +01:00
										 |  |  |     _Py_SetLocaleFromEnv(LC_ALL); | 
					
						
							| 
									
										
										
										
											2019-05-20 17:16:38 +02:00
										 |  |  |     return 1; | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 17:16:38 +02:00
										 |  |  | int | 
					
						
							| 
									
										
										
										
											2018-08-29 13:25:36 +02:00
										 |  |  | _Py_CoerceLegacyLocale(int warn) | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-20 17:16:38 +02:00
										 |  |  |     int coerced = 0; | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  | #ifdef PY_COERCE_C_LOCALE
 | 
					
						
							| 
									
										
										
										
											2018-09-03 17:05:18 +02:00
										 |  |  |     char *oldloc = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     oldloc = _PyMem_RawStrdup(setlocale(LC_CTYPE, NULL)); | 
					
						
							|  |  |  |     if (oldloc == NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-20 17:16:38 +02:00
										 |  |  |         return coerced; | 
					
						
							| 
									
										
										
										
											2018-09-03 17:05:18 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-16 04:54:22 +01:00
										 |  |  |     const char *locale_override = getenv("LC_ALL"); | 
					
						
							|  |  |  |     if (locale_override == NULL || *locale_override == '\0') { | 
					
						
							|  |  |  |         /* LC_ALL is also not set (or is set to an empty string) */ | 
					
						
							|  |  |  |         const _LocaleCoercionTarget *target = NULL; | 
					
						
							|  |  |  |         for (target = _TARGET_LOCALES; target->locale_name; target++) { | 
					
						
							|  |  |  |             const char *new_locale = setlocale(LC_CTYPE, | 
					
						
							|  |  |  |                                                target->locale_name); | 
					
						
							|  |  |  |             if (new_locale != NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-02 11:28:57 -04:00
										 |  |  | #if !defined(_Py_FORCE_UTF8_LOCALE) && defined(HAVE_LANGINFO_H) && defined(CODESET)
 | 
					
						
							| 
									
										
										
										
											2017-12-16 04:54:22 +01:00
										 |  |  |                 /* Also ensure that nl_langinfo works in this locale */ | 
					
						
							|  |  |  |                 char *codeset = nl_langinfo(CODESET); | 
					
						
							|  |  |  |                 if (!codeset || *codeset == '\0') { | 
					
						
							|  |  |  |                     /* CODESET is not set or empty, so skip coercion */ | 
					
						
							|  |  |  |                     new_locale = NULL; | 
					
						
							|  |  |  |                     _Py_SetLocaleFromEnv(LC_CTYPE); | 
					
						
							|  |  |  |                     continue; | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2017-12-16 04:54:22 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |                 /* Successfully configured locale, so make it the default */ | 
					
						
							| 
									
										
										
										
											2019-05-20 17:16:38 +02:00
										 |  |  |                 coerced = _coerce_default_locale_settings(warn, target); | 
					
						
							| 
									
										
										
										
											2018-09-03 17:05:18 +02:00
										 |  |  |                 goto done; | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /* No C locale warning here, as Py_Initialize will emit one later */ | 
					
						
							| 
									
										
										
										
											2018-09-03 17:05:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     setlocale(LC_CTYPE, oldloc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | done: | 
					
						
							|  |  |  |     PyMem_RawFree(oldloc); | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-05-20 17:16:38 +02:00
										 |  |  |     return coerced; | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-12 12:45:59 +01:00
										 |  |  | /* _Py_SetLocaleFromEnv() is a wrapper around setlocale(category, "") to
 | 
					
						
							|  |  |  |  * isolate the idiosyncrasies of different libc implementations. It reads the | 
					
						
							|  |  |  |  * appropriate environment variable and uses its value to select the locale for | 
					
						
							|  |  |  |  * 'category'. */ | 
					
						
							|  |  |  | char * | 
					
						
							|  |  |  | _Py_SetLocaleFromEnv(int category) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-11-23 13:08:26 +01:00
										 |  |  |     char *res; | 
					
						
							| 
									
										
										
										
											2017-11-12 12:45:59 +01:00
										 |  |  | #ifdef __ANDROID__
 | 
					
						
							|  |  |  |     const char *locale; | 
					
						
							|  |  |  |     const char **pvar; | 
					
						
							|  |  |  | #ifdef PY_COERCE_C_LOCALE
 | 
					
						
							|  |  |  |     const char *coerce_c_locale; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     const char *utf8_locale = "C.UTF-8"; | 
					
						
							|  |  |  |     const char *env_var_set[] = { | 
					
						
							|  |  |  |         "LC_ALL", | 
					
						
							|  |  |  |         "LC_CTYPE", | 
					
						
							|  |  |  |         "LANG", | 
					
						
							|  |  |  |         NULL, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Android setlocale(category, "") doesn't check the environment variables
 | 
					
						
							|  |  |  |      * and incorrectly sets the "C" locale at API 24 and older APIs. We only | 
					
						
							|  |  |  |      * check the environment variables listed in env_var_set. */ | 
					
						
							|  |  |  |     for (pvar=env_var_set; *pvar; pvar++) { | 
					
						
							|  |  |  |         locale = getenv(*pvar); | 
					
						
							|  |  |  |         if (locale != NULL && *locale != '\0') { | 
					
						
							|  |  |  |             if (strcmp(locale, utf8_locale) == 0 || | 
					
						
							|  |  |  |                     strcmp(locale, "en_US.UTF-8") == 0) { | 
					
						
							|  |  |  |                 return setlocale(category, utf8_locale); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return setlocale(category, "C"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Android uses UTF-8, so explicitly set the locale to C.UTF-8 if none of
 | 
					
						
							|  |  |  |      * LC_ALL, LC_CTYPE, or LANG is set to a non-empty string. | 
					
						
							|  |  |  |      * Quote from POSIX section "8.2 Internationalization Variables": | 
					
						
							|  |  |  |      * "4. If the LANG environment variable is not set or is set to the empty | 
					
						
							|  |  |  |      * string, the implementation-defined default locale shall be used." */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef PY_COERCE_C_LOCALE
 | 
					
						
							|  |  |  |     coerce_c_locale = getenv("PYTHONCOERCECLOCALE"); | 
					
						
							|  |  |  |     if (coerce_c_locale == NULL || strcmp(coerce_c_locale, "0") != 0) { | 
					
						
							|  |  |  |         /* Some other ported code may check the environment variables (e.g. in
 | 
					
						
							|  |  |  |          * extension modules), so we make sure that they match the locale | 
					
						
							|  |  |  |          * configuration */ | 
					
						
							|  |  |  |         if (setenv("LC_CTYPE", utf8_locale, 1)) { | 
					
						
							|  |  |  |             fprintf(stderr, "Warning: failed setting the LC_CTYPE " | 
					
						
							|  |  |  |                             "environment variable to %s\n", utf8_locale); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-11-23 13:08:26 +01:00
										 |  |  |     res = setlocale(category, utf8_locale); | 
					
						
							|  |  |  | #else /* !defined(__ANDROID__) */
 | 
					
						
							|  |  |  |     res = setlocale(category, ""); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     _Py_ResetForceASCII(); | 
					
						
							|  |  |  |     return res; | 
					
						
							| 
									
										
										
										
											2017-11-12 12:45:59 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 13:16:15 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 00:45:56 +01:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2020-11-10 13:21:52 +01:00
										 |  |  | interpreter_update_config(PyThreadState *tstate, int only_update_path_config) | 
					
						
							| 
									
										
										
										
											2020-11-05 00:45:56 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-11-10 13:21:52 +01:00
										 |  |  |     const PyConfig *config = &tstate->interp->config; | 
					
						
							| 
									
										
										
										
											2020-11-05 00:45:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-10 13:21:52 +01:00
										 |  |  |     if (!only_update_path_config) { | 
					
						
							|  |  |  |         PyStatus status = _PyConfig_Write(config, tstate->interp->runtime); | 
					
						
							|  |  |  |         if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |             _PyErr_SetFromPyStatus(status); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-11-05 00:45:56 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 13:33:31 +01:00
										 |  |  |     if (_Py_IsMainInterpreter(tstate->interp)) { | 
					
						
							| 
									
										
										
										
											2021-12-03 00:08:42 +00:00
										 |  |  |         PyStatus status = _PyPathConfig_UpdateGlobal(config); | 
					
						
							| 
									
										
										
										
											2020-11-05 00:45:56 +01:00
										 |  |  |         if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |             _PyErr_SetFromPyStatus(status); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-19 14:27:46 -06:00
										 |  |  |     tstate->interp->long_state.max_str_digits = config->int_max_str_digits; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 00:45:56 +01:00
										 |  |  |     // Update the sys module for the new configuration
 | 
					
						
							|  |  |  |     if (_PySys_UpdateConfig(tstate) < 0) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | _PyInterpreterState_SetConfig(const PyConfig *src_config) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-10-13 14:09:13 +02:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2020-11-05 00:45:56 +01:00
										 |  |  |     int res = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyConfig config; | 
					
						
							|  |  |  |     PyConfig_InitPythonConfig(&config); | 
					
						
							|  |  |  |     PyStatus status = _PyConfig_Copy(&config, src_config); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         _PyErr_SetFromPyStatus(status); | 
					
						
							|  |  |  |         goto done; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-03 00:08:42 +00:00
										 |  |  |     status = _PyConfig_Read(&config, 1); | 
					
						
							| 
									
										
										
										
											2020-11-05 00:45:56 +01:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         _PyErr_SetFromPyStatus(status); | 
					
						
							|  |  |  |         goto done; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-10 13:21:52 +01:00
										 |  |  |     status = _PyConfig_Copy(&tstate->interp->config, &config); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         _PyErr_SetFromPyStatus(status); | 
					
						
							|  |  |  |         goto done; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     res = interpreter_update_config(tstate, 0); | 
					
						
							| 
									
										
										
										
											2020-11-05 00:45:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | done: | 
					
						
							|  |  |  |     PyConfig_Clear(&config); | 
					
						
							|  |  |  |     return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-23 21:46:51 -07:00
										 |  |  | /* Global initializations.  Can be undone by Py_Finalize().  Don't
 | 
					
						
							|  |  |  |    call this twice without an intervening Py_Finalize() call. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |    Every call to Py_InitializeFromConfig, Py_Initialize or Py_InitializeEx | 
					
						
							| 
									
										
										
										
											2017-05-23 21:46:51 -07:00
										 |  |  |    must have a corresponding call to Py_Finalize. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Locking: you must hold the interpreter lock while calling these APIs. | 
					
						
							|  |  |  |    (If the lock has not yet been initialized, that's equivalent to | 
					
						
							|  |  |  |    having the lock, but you cannot use multiple threads.) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2019-05-23 00:57:57 +02:00
										 |  |  | pyinit_core_reconfigure(_PyRuntimeState *runtime, | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |                         PyThreadState **tstate_p, | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |                         const PyConfig *config) | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyStatus status; | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							|  |  |  |     if (!tstate) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_ERR("failed to read thread state"); | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |     *tstate_p = tstate; | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     PyInterpreterState *interp = tstate->interp; | 
					
						
							|  |  |  |     if (interp == NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_ERR("can't make main interpreter"); | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-08 18:12:59 +02:00
										 |  |  |     status = _PyConfig_Write(config, runtime); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 00:45:56 +01:00
										 |  |  |     status = _PyConfig_Copy(&interp->config, config); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-04-13 03:04:28 +02:00
										 |  |  |     config = _PyInterpreterState_GetConfig(interp); | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (config->_install_importlib) { | 
					
						
							| 
									
										
										
										
											2021-12-03 00:08:42 +00:00
										 |  |  |         status = _PyPathConfig_UpdateGlobal(config); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |             return status; | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2019-04-24 18:23:53 +02:00
										 |  |  | pycore_init_runtime(_PyRuntimeState *runtime, | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |                     const PyConfig *config) | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-24 18:23:53 +02:00
										 |  |  |     if (runtime->initialized) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_ERR("main interpreter already initialized"); | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-12-15 01:46:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-08 18:12:59 +02:00
										 |  |  |     PyStatus status = _PyConfig_Write(config, runtime); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-09-07 23:51:28 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-23 21:46:51 -07:00
										 |  |  |     /* Py_Finalize leaves _Py_Finalizing set in order to help daemon
 | 
					
						
							|  |  |  |      * threads behave a little more gracefully at interpreter shutdown. | 
					
						
							|  |  |  |      * We clobber it here so the new interpreter can start with a clean | 
					
						
							|  |  |  |      * slate. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * However, this may still lead to misbehaviour if there are daemon | 
					
						
							|  |  |  |      * threads still hanging around from a previous Py_Initialize/Finalize | 
					
						
							|  |  |  |      * pair :( | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-03-07 00:24:23 +01:00
										 |  |  |     _PyRuntimeState_SetFinalizing(runtime, NULL); | 
					
						
							| 
									
										
										
										
											2017-09-07 23:51:28 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-15 09:45:11 -07:00
										 |  |  |     _Py_InitVersion(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-08 18:12:59 +02:00
										 |  |  |     status = _Py_HashRandomization_Init(config); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 17:06:05 -07:00
										 |  |  |     status = _PyImport_Init(); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = _PyInterpreterState_Enable(runtime); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2017-11-15 18:11:45 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-11-15 18:11:45 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-24 17:23:57 -06:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2023-05-02 21:40:00 -06:00
										 |  |  | init_interp_settings(PyInterpreterState *interp, | 
					
						
							|  |  |  |                      const PyInterpreterConfig *config) | 
					
						
							| 
									
										
										
										
											2022-10-26 11:16:30 -06:00
										 |  |  | { | 
					
						
							|  |  |  |     assert(interp->feature_flags == 0); | 
					
						
							| 
									
										
										
											
												gh-98610: Adjust the Optional Restrictions on Subinterpreters (GH-98618)
Previously, the optional restrictions on subinterpreters were: disallow fork, subprocess, and threads.  By default, we were disallowing all three for "isolated" interpreters.  We always allowed all three for the main interpreter and those created through the legacy `Py_NewInterpreter()` API.
Those settings were a bit conservative, so here we've adjusted the optional restrictions to: fork, exec, threads, and daemon threads.  The default for "isolated" interpreters disables fork, exec, and daemon threads.  Regular threads are allowed by default.  We continue always allowing everything For the main interpreter and the legacy API.
In the code, we add `_PyInterpreterConfig.allow_exec` and  `_PyInterpreterConfig.allow_daemon_threads`.  We also add `Py_RTFLAGS_DAEMON_THREADS` and `Py_RTFLAGS_EXEC`.
											
										 
											2022-10-31 13:35:54 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-24 17:23:57 -06:00
										 |  |  |     if (config->use_main_obmalloc) { | 
					
						
							|  |  |  |         interp->feature_flags |= Py_RTFLAGS_USE_MAIN_OBMALLOC; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (!config->check_multi_interp_extensions) { | 
					
						
							|  |  |  |         /* The reason: PyModuleDef.m_base.m_copy leaks objects between
 | 
					
						
							|  |  |  |            interpreters. */ | 
					
						
							|  |  |  |         return _PyStatus_ERR("per-interpreter obmalloc does not support " | 
					
						
							|  |  |  |                              "single-phase init extension modules"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-26 11:16:30 -06:00
										 |  |  |     if (config->allow_fork) { | 
					
						
							|  |  |  |         interp->feature_flags |= Py_RTFLAGS_FORK; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
											
												gh-98610: Adjust the Optional Restrictions on Subinterpreters (GH-98618)
Previously, the optional restrictions on subinterpreters were: disallow fork, subprocess, and threads.  By default, we were disallowing all three for "isolated" interpreters.  We always allowed all three for the main interpreter and those created through the legacy `Py_NewInterpreter()` API.
Those settings were a bit conservative, so here we've adjusted the optional restrictions to: fork, exec, threads, and daemon threads.  The default for "isolated" interpreters disables fork, exec, and daemon threads.  Regular threads are allowed by default.  We continue always allowing everything For the main interpreter and the legacy API.
In the code, we add `_PyInterpreterConfig.allow_exec` and  `_PyInterpreterConfig.allow_daemon_threads`.  We also add `Py_RTFLAGS_DAEMON_THREADS` and `Py_RTFLAGS_EXEC`.
											
										 
											2022-10-31 13:35:54 -06:00
										 |  |  |     if (config->allow_exec) { | 
					
						
							|  |  |  |         interp->feature_flags |= Py_RTFLAGS_EXEC; | 
					
						
							| 
									
										
										
										
											2022-10-26 11:16:30 -06:00
										 |  |  |     } | 
					
						
							| 
									
										
										
											
												gh-98610: Adjust the Optional Restrictions on Subinterpreters (GH-98618)
Previously, the optional restrictions on subinterpreters were: disallow fork, subprocess, and threads.  By default, we were disallowing all three for "isolated" interpreters.  We always allowed all three for the main interpreter and those created through the legacy `Py_NewInterpreter()` API.
Those settings were a bit conservative, so here we've adjusted the optional restrictions to: fork, exec, threads, and daemon threads.  The default for "isolated" interpreters disables fork, exec, and daemon threads.  Regular threads are allowed by default.  We continue always allowing everything For the main interpreter and the legacy API.
In the code, we add `_PyInterpreterConfig.allow_exec` and  `_PyInterpreterConfig.allow_daemon_threads`.  We also add `Py_RTFLAGS_DAEMON_THREADS` and `Py_RTFLAGS_EXEC`.
											
										 
											2022-10-31 13:35:54 -06:00
										 |  |  |     // Note that fork+exec is always allowed.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-26 11:16:30 -06:00
										 |  |  |     if (config->allow_threads) { | 
					
						
							|  |  |  |         interp->feature_flags |= Py_RTFLAGS_THREADS; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
											
												gh-98610: Adjust the Optional Restrictions on Subinterpreters (GH-98618)
Previously, the optional restrictions on subinterpreters were: disallow fork, subprocess, and threads.  By default, we were disallowing all three for "isolated" interpreters.  We always allowed all three for the main interpreter and those created through the legacy `Py_NewInterpreter()` API.
Those settings were a bit conservative, so here we've adjusted the optional restrictions to: fork, exec, threads, and daemon threads.  The default for "isolated" interpreters disables fork, exec, and daemon threads.  Regular threads are allowed by default.  We continue always allowing everything For the main interpreter and the legacy API.
In the code, we add `_PyInterpreterConfig.allow_exec` and  `_PyInterpreterConfig.allow_daemon_threads`.  We also add `Py_RTFLAGS_DAEMON_THREADS` and `Py_RTFLAGS_EXEC`.
											
										 
											2022-10-31 13:35:54 -06:00
										 |  |  |     if (config->allow_daemon_threads) { | 
					
						
							|  |  |  |         interp->feature_flags |= Py_RTFLAGS_DAEMON_THREADS; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-02-15 18:16:00 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (config->check_multi_interp_extensions) { | 
					
						
							|  |  |  |         interp->feature_flags |= Py_RTFLAGS_MULTI_INTERP_EXTENSIONS; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-24 17:23:57 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-12 19:20:21 -05:00
										 |  |  |     switch (config->gil) { | 
					
						
							|  |  |  |     case PyInterpreterConfig_DEFAULT_GIL: break; | 
					
						
							|  |  |  |     case PyInterpreterConfig_SHARED_GIL: break; | 
					
						
							|  |  |  |     case PyInterpreterConfig_OWN_GIL: break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         return _PyStatus_ERR("invalid interpreter config 'gil' value"); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-06-13 11:08:32 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-24 17:23:57 -06:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2022-10-26 11:16:30 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-12 19:20:21 -05:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2023-06-13 11:08:32 -06:00
										 |  |  | init_interp_create_gil(PyThreadState *tstate, int gil) | 
					
						
							| 
									
										
										
										
											2020-04-08 17:54:59 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     /* finalize_interp_delete() comment explains why _PyEval_FiniGIL() is
 | 
					
						
							|  |  |  |        only called here. */ | 
					
						
							| 
									
										
										
										
											2023-05-06 15:59:30 -06:00
										 |  |  |     // XXX This is broken with a per-interpreter GIL.
 | 
					
						
							| 
									
										
										
										
											2021-02-19 15:10:45 +01:00
										 |  |  |     _PyEval_FiniGIL(tstate->interp); | 
					
						
							| 
									
										
										
										
											2020-04-08 17:54:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Auto-thread-state API */ | 
					
						
							| 
									
										
										
										
											2023-12-12 19:20:21 -05:00
										 |  |  |     _PyGILState_SetTstate(tstate); | 
					
						
							| 
									
										
										
										
											2020-04-08 17:54:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-12 19:20:21 -05:00
										 |  |  |     int own_gil = (gil == PyInterpreterConfig_OWN_GIL); | 
					
						
							| 
									
										
										
										
											2023-06-13 11:08:32 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-08 17:54:59 +02:00
										 |  |  |     /* Create the GIL and take it */ | 
					
						
							| 
									
										
										
										
											2023-12-12 19:20:21 -05:00
										 |  |  |     _PyEval_InitGIL(tstate, own_gil); | 
					
						
							| 
									
										
										
										
											2020-04-08 17:54:59 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-25 06:10:51 -05:00
										 |  |  | static int | 
					
						
							|  |  |  | builtins_dict_watcher(PyDict_WatchEvent event, PyObject *dict, PyObject *key, PyObject *new_value) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-02-02 12:14:34 +00:00
										 |  |  |     PyInterpreterState *interp = _PyInterpreterState_GET(); | 
					
						
							| 
									
										
										
										
											2024-02-12 16:07:38 +00:00
										 |  |  |     if (interp->rare_events.builtin_dict < _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS) { | 
					
						
							| 
									
										
										
										
											2024-02-26 12:51:47 -05:00
										 |  |  |         _Py_Executors_InvalidateAll(interp, 1); | 
					
						
							| 
									
										
										
										
											2024-02-02 12:14:34 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     RARE_EVENT_INTERP_INC(interp, builtin_dict); | 
					
						
							| 
									
										
										
										
											2024-01-25 06:10:51 -05:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-04-08 17:54:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2019-04-24 18:23:53 +02:00
										 |  |  | pycore_create_interpreter(_PyRuntimeState *runtime, | 
					
						
							| 
									
										
										
										
											2022-10-26 11:16:30 -06:00
										 |  |  |                           const PyConfig *src_config, | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |                           PyThreadState **tstate_p) | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-19 16:04:14 -07:00
										 |  |  |     PyStatus status; | 
					
						
							| 
									
										
										
										
											2023-09-01 12:43:30 +02:00
										 |  |  |     PyInterpreterState *interp; | 
					
						
							|  |  |  |     status = _PyInterpreterState_New(NULL, &interp); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2017-12-15 01:46:02 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-09-01 12:43:30 +02:00
										 |  |  |     assert(interp != NULL); | 
					
						
							| 
									
										
										
										
											2021-03-10 20:00:46 +01:00
										 |  |  |     assert(_Py_IsMainInterpreter(interp)); | 
					
						
							| 
									
										
										
										
											2017-12-15 01:46:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-26 11:16:30 -06:00
										 |  |  |     status = _PyConfig_Copy(&interp->config, src_config); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2017-12-15 01:46:02 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-19 16:04:14 -07:00
										 |  |  |     /* Auto-thread-state API */ | 
					
						
							|  |  |  |     status = _PyGILState_Init(interp); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-05 15:59:20 -06:00
										 |  |  |     PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT; | 
					
						
							|  |  |  |     // The main interpreter always has its own GIL.
 | 
					
						
							| 
									
										
										
										
											2023-06-13 11:08:32 -06:00
										 |  |  |     config.gil = PyInterpreterConfig_OWN_GIL; | 
					
						
							| 
									
										
										
										
											2023-04-24 17:23:57 -06:00
										 |  |  |     status = init_interp_settings(interp, &config); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-10-26 11:16:30 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 19:38:14 -08:00
										 |  |  |     // initialize the interp->obmalloc state.  This must be done after
 | 
					
						
							|  |  |  |     // the settings are loaded (so that feature_flags are set) but before
 | 
					
						
							|  |  |  |     // any calls are made to obmalloc functions.
 | 
					
						
							|  |  |  |     if (_PyMem_init_obmalloc(interp) < 0) { | 
					
						
							|  |  |  |         return  _PyStatus_NO_MEMORY(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-03 09:20:48 -06:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_New(interp, | 
					
						
							|  |  |  |                                                _PyThreadState_WHENCE_INTERP); | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |     if (tstate == NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_ERR("can't make first thread"); | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-02-20 06:57:48 -08:00
										 |  |  |     runtime->main_tstate = tstate; | 
					
						
							| 
									
										
										
										
											2023-01-30 12:07:48 -07:00
										 |  |  |     _PyThreadState_Bind(tstate); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-12 19:20:21 -05:00
										 |  |  |     init_interp_create_gil(tstate, config.gil); | 
					
						
							| 
									
										
										
										
											2018-01-29 11:57:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |     *tstate_p = tstate; | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  | pycore_init_global_objects(PyInterpreterState *interp) | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-20 01:18:11 +01:00
										 |  |  |     PyStatus status; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  |     _PyFloat_InitState(interp); | 
					
						
							| 
									
										
										
										
											2021-04-02 15:28:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  |     status = _PyUnicode_InitGlobalObjects(interp); | 
					
						
							| 
									
										
										
										
											2019-11-20 01:18:11 +01:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  |     _PyUnicode_InitState(interp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-02 15:28:13 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyStatus | 
					
						
							|  |  |  | pycore_init_types(PyInterpreterState *interp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyStatus status; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  |     status = _PyTypes_InitTypes(interp); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-11-20 00:38:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  |     status = _PyLong_InitTypes(interp); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  |     status = _PyUnicode_InitTypes(interp); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  |     status = _PyFloat_InitTypes(interp); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-05-22 11:28:22 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-22 21:48:56 +01:00
										 |  |  |     if (_PyExc_InitTypes(interp) < 0) { | 
					
						
							|  |  |  |         return _PyStatus_ERR("failed to initialize an exception type"); | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     status = _PyExc_InitGlobalObjects(interp); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     status = _PyExc_InitState(interp); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     status = _PyErr_InitTypes(interp); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-22 18:55:48 +01:00
										 |  |  |     status = _PyContext_Init(interp); | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-11-20 00:38:03 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-11-01 17:36:40 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-12 08:24:31 -07:00
										 |  |  |     status = _PyXI_InitTypes(interp); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2021-04-02 15:28:13 +02:00
										 |  |  | pycore_init_builtins(PyThreadState *tstate) | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-04-02 15:28:13 +02:00
										 |  |  |     PyInterpreterState *interp = tstate->interp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 15:10:45 +01:00
										 |  |  |     PyObject *bimod = _PyBuiltin_Init(interp); | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  |     if (bimod == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-22 19:24:49 +01:00
										 |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  |     PyObject *modules = _PyImport_GetModules(interp); | 
					
						
							|  |  |  |     if (_PyImport_FixupBuiltin(bimod, "builtins", modules) < 0) { | 
					
						
							| 
									
										
										
										
											2019-11-22 19:24:49 +01:00
										 |  |  |         goto error; | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-22 19:24:49 +01:00
										 |  |  |     PyObject *builtins_dict = PyModule_GetDict(bimod); | 
					
						
							|  |  |  |     if (builtins_dict == NULL) { | 
					
						
							|  |  |  |         goto error; | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-10 09:03:39 +01:00
										 |  |  |     interp->builtins = Py_NewRef(builtins_dict); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-23 17:40:26 +02:00
										 |  |  |     PyObject *isinstance = PyDict_GetItemWithError(builtins_dict, &_Py_ID(isinstance)); | 
					
						
							|  |  |  |     if (!isinstance) { | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-03-07 11:45:00 -08:00
										 |  |  |     interp->callable_cache.isinstance = isinstance; | 
					
						
							| 
									
										
										
										
											2023-08-23 17:40:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     PyObject *len = PyDict_GetItemWithError(builtins_dict, &_Py_ID(len)); | 
					
						
							|  |  |  |     if (!len) { | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-03-07 11:45:00 -08:00
										 |  |  |     interp->callable_cache.len = len; | 
					
						
							| 
									
										
										
										
											2023-08-23 17:40:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-07 11:45:00 -08:00
										 |  |  |     PyObject *list_append = _PyType_Lookup(&PyList_Type, &_Py_ID(append)); | 
					
						
							| 
									
										
										
										
											2023-08-23 17:40:26 +02:00
										 |  |  |     if (list_append == NULL) { | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-03-07 11:45:00 -08:00
										 |  |  |     interp->callable_cache.list_append = list_append; | 
					
						
							| 
									
										
										
										
											2023-08-23 17:40:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-17 19:37:07 +08:00
										 |  |  |     PyObject *object__getattribute__ = _PyType_Lookup(&PyBaseObject_Type, &_Py_ID(__getattribute__)); | 
					
						
							| 
									
										
										
										
											2023-08-23 17:40:26 +02:00
										 |  |  |     if (object__getattribute__ == NULL) { | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-17 19:37:07 +08:00
										 |  |  |     interp->callable_cache.object__getattribute__ = object__getattribute__; | 
					
						
							| 
									
										
										
										
											2023-08-23 17:40:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-22 21:48:56 +01:00
										 |  |  |     if (_PyBuiltins_AddExceptions(bimod) < 0) { | 
					
						
							|  |  |  |         return _PyStatus_ERR("failed to add exceptions to builtins"); | 
					
						
							| 
									
										
										
										
											2019-01-22 17:39:03 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-11-22 19:24:49 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     interp->builtins_copy = PyDict_Copy(interp->builtins); | 
					
						
							|  |  |  |     if (interp->builtins_copy == NULL) { | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-12-04 11:19:59 +00:00
										 |  |  |     Py_DECREF(bimod); | 
					
						
							| 
									
										
										
										
											2019-12-06 02:43:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  |     if (_PyImport_InitDefaultImportFunc(interp) < 0) { | 
					
						
							| 
									
										
										
										
											2020-11-18 23:18:29 +01:00
										 |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-02 15:28:13 +02:00
										 |  |  |     assert(!_PyErr_Occurred(tstate)); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-11-22 19:24:49 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | error: | 
					
						
							| 
									
										
										
										
											2019-12-04 11:19:59 +00:00
										 |  |  |     Py_XDECREF(bimod); | 
					
						
							| 
									
										
										
										
											2019-11-22 19:24:49 +01:00
										 |  |  |     return _PyStatus_ERR("can't initialize builtins module"); | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2019-12-06 03:37:07 +01:00
										 |  |  | pycore_interp_init(PyThreadState *tstate) | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-04-02 15:28:13 +02:00
										 |  |  |     PyInterpreterState *interp = tstate->interp; | 
					
						
							| 
									
										
										
										
											2019-12-06 03:37:07 +01:00
										 |  |  |     PyStatus status; | 
					
						
							| 
									
										
										
										
											2019-12-08 21:55:58 +01:00
										 |  |  |     PyObject *sysmod = NULL; | 
					
						
							| 
									
										
										
										
											2019-03-26 02:31:11 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-02 15:28:13 +02:00
										 |  |  |     // Create singletons before the first PyType_Ready() call, since
 | 
					
						
							|  |  |  |     // PyType_Ready() uses singletons like the Unicode empty string (tp_doc)
 | 
					
						
							|  |  |  |     // and the empty tuple singletons (tp_bases).
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  |     status = pycore_init_global_objects(interp); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							| 
									
										
										
										
											2021-04-02 15:28:13 +02:00
										 |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-07 08:47:55 -05:00
										 |  |  |     status = _PyDtoa_Init(interp); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-02 15:28:13 +02:00
										 |  |  |     // The GC must be initialized before the first GC collection.
 | 
					
						
							|  |  |  |     status = _PyGC_Init(interp); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-02-25 16:19:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-02 15:28:13 +02:00
										 |  |  |     status = pycore_init_types(interp); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							| 
									
										
										
										
											2019-12-08 21:55:58 +01:00
										 |  |  |         goto done; | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-02 15:28:13 +02:00
										 |  |  |     if (_PyWarnings_InitState(interp) < 0) { | 
					
						
							|  |  |  |         return _PyStatus_ERR("can't initialize warnings"); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-02-19 15:10:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-02 15:28:13 +02:00
										 |  |  |     status = _PyAtExit_Init(interp); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     status = _PySys_Create(tstate, &sysmod); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							| 
									
										
										
										
											2019-12-08 21:55:58 +01:00
										 |  |  |         goto done; | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-02 15:28:13 +02:00
										 |  |  |     status = pycore_init_builtins(tstate); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         goto done; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-02-19 15:10:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-01 17:36:40 -06:00
										 |  |  |     status = _PyXI_Init(interp); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         goto done; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-02 15:28:13 +02:00
										 |  |  |     const PyConfig *config = _PyInterpreterState_GetConfig(interp); | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     status = _PyImport_InitCore(tstate, sysmod, config->_install_importlib); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         goto done; | 
					
						
							| 
									
										
										
										
											2020-11-12 15:14:13 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-12-08 21:55:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | done: | 
					
						
							|  |  |  |     /* sys.modules['sys'] contains a strong reference to the module */ | 
					
						
							|  |  |  |     Py_XDECREF(sysmod); | 
					
						
							|  |  |  |     return status; | 
					
						
							| 
									
										
										
										
											2019-12-06 03:37:07 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyStatus | 
					
						
							|  |  |  | pyinit_config(_PyRuntimeState *runtime, | 
					
						
							|  |  |  |               PyThreadState **tstate_p, | 
					
						
							|  |  |  |               const PyConfig *config) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyStatus status = pycore_init_runtime(runtime, config); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-06 03:37:07 +01:00
										 |  |  |     PyThreadState *tstate; | 
					
						
							|  |  |  |     status = pycore_create_interpreter(runtime, config, &tstate); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-12-06 03:37:07 +01:00
										 |  |  |     *tstate_p = tstate; | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-06 03:37:07 +01:00
										 |  |  |     status = pycore_interp_init(tstate); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-05-23 21:46:51 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Only when we get here is the runtime core fully initialized */ | 
					
						
							| 
									
										
										
										
											2019-04-24 18:23:53 +02:00
										 |  |  |     runtime->core_initialized = 1; | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2017-05-23 21:46:51 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-06 00:36:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | PyStatus | 
					
						
							|  |  |  | _Py_PreInitializeFromPyArgv(const PyPreConfig *src_config, const _PyArgv *args) | 
					
						
							| 
									
										
										
										
											2019-03-06 00:36:56 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyStatus status; | 
					
						
							| 
									
										
										
										
											2019-03-20 02:20:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |     if (src_config == NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_ERR("preinitialization config is NULL"); | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = _PyRuntime_Initialize(); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-03-20 02:20:13 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-24 18:23:53 +02:00
										 |  |  |     _PyRuntimeState *runtime = &_PyRuntime; | 
					
						
							| 
									
										
										
										
											2019-03-20 02:20:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-17 23:59:51 +02:00
										 |  |  |     if (runtime->preinitialized) { | 
					
						
							| 
									
										
										
										
											2019-03-25 17:54:58 +01:00
										 |  |  |         /* If it's already configured: ignored the new configuration */ | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-03-25 18:37:10 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-17 23:59:51 +02:00
										 |  |  |     /* Note: preinitialized remains 1 on error, it is only set to 0
 | 
					
						
							|  |  |  |        at exit on success. */ | 
					
						
							|  |  |  |     runtime->preinitializing = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyPreConfig config; | 
					
						
							| 
									
										
										
										
											2019-09-28 04:28:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     status = _PyPreConfig_InitFromPreConfig(&config, src_config); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-25 17:54:58 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = _PyPreConfig_Read(&config, args); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-03-06 00:36:56 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = _PyPreConfig_Write(&config); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-03-20 02:20:13 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-17 23:59:51 +02:00
										 |  |  |     runtime->preinitializing = 0; | 
					
						
							|  |  |  |     runtime->preinitialized = 1; | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-03-20 02:20:13 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-02 15:25:34 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | PyStatus | 
					
						
							|  |  |  | Py_PreInitializeFromBytesArgs(const PyPreConfig *src_config, Py_ssize_t argc, char **argv) | 
					
						
							| 
									
										
										
										
											2019-03-25 18:37:10 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-27 13:40:14 +01:00
										 |  |  |     _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv}; | 
					
						
							| 
									
										
										
										
											2019-05-02 15:25:34 -04:00
										 |  |  |     return _Py_PreInitializeFromPyArgv(src_config, &args); | 
					
						
							| 
									
										
										
										
											2019-03-25 18:37:10 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | PyStatus | 
					
						
							|  |  |  | Py_PreInitializeFromArgs(const PyPreConfig *src_config, Py_ssize_t argc, wchar_t **argv) | 
					
						
							| 
									
										
										
										
											2019-03-26 02:31:11 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-27 13:40:14 +01:00
										 |  |  |     _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv}; | 
					
						
							| 
									
										
										
										
											2019-05-02 15:25:34 -04:00
										 |  |  |     return _Py_PreInitializeFromPyArgv(src_config, &args); | 
					
						
							| 
									
										
										
										
											2019-03-26 02:31:11 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | PyStatus | 
					
						
							|  |  |  | Py_PreInitialize(const PyPreConfig *src_config) | 
					
						
							| 
									
										
										
										
											2019-03-20 02:20:13 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-02 15:25:34 -04:00
										 |  |  |     return _Py_PreInitializeFromPyArgv(src_config, NULL); | 
					
						
							| 
									
										
										
										
											2019-03-25 17:54:58 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-03-06 00:36:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-20 02:20:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | PyStatus | 
					
						
							|  |  |  | _Py_PreInitializeFromConfig(const PyConfig *config, | 
					
						
							|  |  |  |                             const _PyArgv *args) | 
					
						
							| 
									
										
										
										
											2019-03-25 17:54:58 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     assert(config != NULL); | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyStatus status = _PyRuntime_Initialize(); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     _PyRuntimeState *runtime = &_PyRuntime; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-17 23:59:51 +02:00
										 |  |  |     if (runtime->preinitialized) { | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |         /* Already initialized: do nothing */ | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyPreConfig preconfig; | 
					
						
							| 
									
										
										
										
											2019-09-28 04:28:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 10:56:37 +02:00
										 |  |  |     _PyPreConfig_InitFromConfig(&preconfig, config); | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (!config->parse_argv) { | 
					
						
							|  |  |  |         return Py_PreInitialize(&preconfig); | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else if (args == NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  |         _PyArgv config_args = { | 
					
						
							|  |  |  |             .use_bytes_argv = 0, | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |             .argc = config->argv.length, | 
					
						
							|  |  |  |             .wchar_argv = config->argv.items}; | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |         return _Py_PreInitializeFromPyArgv(&preconfig, &config_args); | 
					
						
							| 
									
										
										
										
											2019-05-17 19:01:14 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |         return _Py_PreInitializeFromPyArgv(&preconfig, args); | 
					
						
							| 
									
										
										
										
											2019-05-02 15:25:34 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-06 00:36:56 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-22 21:18:05 +01:00
										 |  |  | /* Begin interpreter initialization
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * On return, the first thread and interpreter state have been created, | 
					
						
							|  |  |  |  * but the compiler, signal handling, multithreading and | 
					
						
							|  |  |  |  * multiple interpreter support, and codec infrastructure are not yet | 
					
						
							|  |  |  |  * available. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The import system will support builtin and frozen modules only. | 
					
						
							|  |  |  |  * The only supported io is writing to sys.stderr | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * If any operation invoked by this function fails, a fatal error is | 
					
						
							|  |  |  |  * issued and the function does not return. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Any code invoked from this function should *not* assume it has access | 
					
						
							|  |  |  |  * to the Python C API (unless the API is explicitly listed as being | 
					
						
							|  |  |  |  * safe to call without calling Py_Initialize first) | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2019-05-23 00:57:57 +02:00
										 |  |  | pyinit_core(_PyRuntimeState *runtime, | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |             const PyConfig *src_config, | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |             PyThreadState **tstate_p) | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyStatus status; | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = _Py_PreInitializeFromConfig(src_config, NULL); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyConfig config; | 
					
						
							| 
									
										
										
										
											2020-11-05 00:45:56 +01:00
										 |  |  |     PyConfig_InitPythonConfig(&config); | 
					
						
							| 
									
										
										
										
											2019-05-23 00:57:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = _PyConfig_Copy(&config, src_config); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							| 
									
										
										
										
											2019-05-23 00:57:57 +02:00
										 |  |  |         goto done; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-10 13:21:52 +01:00
										 |  |  |     // Read the configuration, but don't compute the path configuration
 | 
					
						
							|  |  |  |     // (it is computed in the main init).
 | 
					
						
							|  |  |  |     status = _PyConfig_Read(&config, 0); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							| 
									
										
										
										
											2019-05-23 00:57:57 +02:00
										 |  |  |         goto done; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!runtime->core_initialized) { | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |         status = pyinit_config(runtime, tstate_p, &config); | 
					
						
							| 
									
										
										
										
											2019-05-23 00:57:57 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |         status = pyinit_core_reconfigure(runtime, tstate_p, &config); | 
					
						
							| 
									
										
										
										
											2019-05-23 00:57:57 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							| 
									
										
										
										
											2019-05-23 00:57:57 +02:00
										 |  |  |         goto done; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | done: | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyConfig_Clear(&config); | 
					
						
							|  |  |  |     return status; | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:40:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-20 17:34:23 +02:00
										 |  |  | /* Py_Initialize() has already been called: update the main interpreter
 | 
					
						
							|  |  |  |    configuration. Example of bpo-34008: Py_Main() called after | 
					
						
							|  |  |  |    Py_Initialize(). */ | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2020-11-04 17:34:34 +01:00
										 |  |  | pyinit_main_reconfigure(PyThreadState *tstate) | 
					
						
							| 
									
										
										
										
											2018-07-20 17:34:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-11-10 13:21:52 +01:00
										 |  |  |     if (interpreter_update_config(tstate, 0) < 0) { | 
					
						
							|  |  |  |         return _PyStatus_ERR("fail to reconfigure Python"); | 
					
						
							| 
									
										
										
										
											2018-07-20 17:34:23 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2018-07-20 17:34:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-14 23:32:57 +02:00
										 |  |  | #ifdef Py_DEBUG
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | run_presite(PyThreadState *tstate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyInterpreterState *interp = tstate->interp; | 
					
						
							|  |  |  |     const PyConfig *config = _PyInterpreterState_GetConfig(interp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!config->run_presite) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyObject *presite_modname = PyUnicode_FromWideChar( | 
					
						
							|  |  |  |         config->run_presite, | 
					
						
							|  |  |  |         wcslen(config->run_presite) | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |     if (presite_modname == NULL) { | 
					
						
							|  |  |  |         fprintf(stderr, "Could not convert pre-site module name to unicode\n"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         PyObject *presite = PyImport_Import(presite_modname); | 
					
						
							|  |  |  |         if (presite == NULL) { | 
					
						
							|  |  |  |             fprintf(stderr, "pre-site import failed:\n"); | 
					
						
							|  |  |  |             _PyErr_Print(tstate); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         Py_XDECREF(presite); | 
					
						
							|  |  |  |         Py_DECREF(presite_modname); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  | init_interp_main(PyThreadState *tstate) | 
					
						
							| 
									
										
										
										
											2017-05-23 21:46:51 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-12-06 02:43:30 +01:00
										 |  |  |     assert(!_PyErr_Occurred(tstate)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  |     PyStatus status; | 
					
						
							| 
									
										
										
										
											2021-02-19 13:33:31 +01:00
										 |  |  |     int is_main_interp = _Py_IsMainInterpreter(tstate->interp); | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |     PyInterpreterState *interp = tstate->interp; | 
					
						
							| 
									
										
										
										
											2020-04-13 03:04:28 +02:00
										 |  |  |     const PyConfig *config = _PyInterpreterState_GetConfig(interp); | 
					
						
							| 
									
										
										
										
											2017-05-23 23:00:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (!config->_install_importlib) { | 
					
						
							| 
									
										
										
										
											2017-05-23 21:46:51 -07:00
										 |  |  |         /* Special mode for freeze_importlib: run with no import system
 | 
					
						
							|  |  |  |          * | 
					
						
							|  |  |  |          * This means anything which needs support from extension modules | 
					
						
							|  |  |  |          * or pure Python code in the standard library won't work. | 
					
						
							|  |  |  |          */ | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  |         if (is_main_interp) { | 
					
						
							|  |  |  |             interp->runtime->initialized = 1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2017-05-23 21:46:51 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-11-25 03:17:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-14 17:31:45 -06:00
										 |  |  |     // Initialize the import-related configuration.
 | 
					
						
							|  |  |  |     status = _PyConfig_InitImportConfig(&interp->config); | 
					
						
							| 
									
										
										
										
											2020-11-10 13:21:52 +01:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (interpreter_update_config(tstate, 1) < 0) { | 
					
						
							|  |  |  |         return _PyStatus_ERR("failed to update the Python config"); | 
					
						
							| 
									
										
										
										
											2017-12-15 01:46:02 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-11-15 18:11:45 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  |     status = _PyImport_InitExternal(tstate); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  |     if (is_main_interp) { | 
					
						
							|  |  |  |         /* initialize the faulthandler module */ | 
					
						
							|  |  |  |         status = _PyFaulthandler_Init(config->faulthandler); | 
					
						
							|  |  |  |         if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |             return status; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |     status = _PyUnicode_InitEncodings(tstate); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  |     if (is_main_interp) { | 
					
						
							| 
									
										
										
										
											2020-11-17 16:22:23 +01:00
										 |  |  |         if (_PySignal_Init(config->install_signal_handlers) < 0) { | 
					
						
							|  |  |  |             return _PyStatus_ERR("can't initialize signals"); | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-17 14:17:16 +01:00
										 |  |  |         if (config->tracemalloc) { | 
					
						
							|  |  |  |            if (_PyTraceMalloc_Start(config->tracemalloc) < 0) { | 
					
						
							|  |  |  |                 return _PyStatus_ERR("can't start tracemalloc"); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-08-30 18:11:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef PY_HAVE_PERF_TRAMPOLINE
 | 
					
						
							|  |  |  |         if (config->perf_profiling) { | 
					
						
							|  |  |  |             if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_callbacks) < 0 || | 
					
						
							|  |  |  |                     _PyPerfTrampoline_Init(config->perf_profiling) < 0) { | 
					
						
							|  |  |  |                 return _PyStatus_ERR("can't initialize the perf trampoline"); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-07-24 13:55:48 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  |     status = init_sys_streams(tstate); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-11-15 18:11:45 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-12 02:49:05 -05:00
										 |  |  |     status = init_set_builtins_open(); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-14 23:32:57 +02:00
										 |  |  | #ifdef Py_DEBUG
 | 
					
						
							|  |  |  |     run_presite(tstate); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  |     status = add_main_module(interp); | 
					
						
							| 
									
										
										
										
											2019-11-22 16:19:14 +01:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  |     if (is_main_interp) { | 
					
						
							|  |  |  |         /* Initialize warnings. */ | 
					
						
							|  |  |  |         PyObject *warnoptions = PySys_GetObject("warnoptions"); | 
					
						
							|  |  |  |         if (warnoptions != NULL && PyList_Size(warnoptions) > 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             PyObject *warnings_module = PyImport_ImportModule("warnings"); | 
					
						
							|  |  |  |             if (warnings_module == NULL) { | 
					
						
							|  |  |  |                 fprintf(stderr, "'import warnings' failed; traceback:\n"); | 
					
						
							|  |  |  |                 _PyErr_Print(tstate); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             Py_XDECREF(warnings_module); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  |         interp->runtime->initialized = 1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-05-23 21:46:51 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (config->site_import) { | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |         status = init_import_site(); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |             return status; | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-08-29 22:56:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  |     if (is_main_interp) { | 
					
						
							| 
									
										
										
										
											2018-08-29 22:56:06 +02:00
										 |  |  | #ifndef MS_WINDOWS
 | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  |         emit_stderr_warning_for_legacy_locale(interp->runtime); | 
					
						
							| 
									
										
										
										
											2018-08-29 22:56:06 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-08-29 22:56:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-26 19:02:57 -07:00
										 |  |  |     // Turn on experimental tier 2 (uops-based) optimizer
 | 
					
						
							|  |  |  |     if (is_main_interp) { | 
					
						
							| 
									
										
										
										
											2024-01-28 18:48:48 -08:00
										 |  |  | #ifndef _Py_JIT
 | 
					
						
							|  |  |  |         // No JIT, maybe use the tier two interpreter:
 | 
					
						
							| 
									
										
										
										
											2023-11-01 13:13:02 -07:00
										 |  |  |         char *envvar = Py_GETENV("PYTHON_UOPS"); | 
					
						
							| 
									
										
										
										
											2023-06-26 19:02:57 -07:00
										 |  |  |         int enabled = envvar != NULL && *envvar > '0'; | 
					
						
							|  |  |  |         if (_Py_get_xoption(&config->xoptions, L"uops") != NULL) { | 
					
						
							|  |  |  |             enabled = 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (enabled) { | 
					
						
							| 
									
										
										
										
											2024-01-28 18:48:48 -08:00
										 |  |  | #else
 | 
					
						
							|  |  |  |         // Always enable tier two for JIT builds (ignoring the environment
 | 
					
						
							|  |  |  |         // variable and command-line option above):
 | 
					
						
							|  |  |  |         if (true) { | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2023-06-26 19:02:57 -07:00
										 |  |  |             PyObject *opt = PyUnstable_Optimizer_NewUOpOptimizer(); | 
					
						
							| 
									
										
										
										
											2023-07-20 09:35:39 -07:00
										 |  |  |             if (opt == NULL) { | 
					
						
							|  |  |  |                 return _PyStatus_ERR("can't initialize optimizer"); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-02-20 09:39:55 +00:00
										 |  |  |             if (PyUnstable_SetOptimizer((_PyOptimizerObject *)opt)) { | 
					
						
							|  |  |  |                 return _PyStatus_ERR("can't initialize optimizer"); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-07-20 09:35:39 -07:00
										 |  |  |             Py_DECREF(opt); | 
					
						
							| 
									
										
										
										
											2023-06-26 19:02:57 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-02 13:59:05 -06:00
										 |  |  |     if (!is_main_interp) { | 
					
						
							|  |  |  |         // The main interpreter is handled in Py_Main(), for now.
 | 
					
						
							|  |  |  |         if (config->sys_path_0 != NULL) { | 
					
						
							|  |  |  |             PyObject *path0 = PyUnicode_FromWideChar(config->sys_path_0, -1); | 
					
						
							|  |  |  |             if (path0 == NULL) { | 
					
						
							|  |  |  |                 return _PyStatus_ERR("can't initialize sys.path[0]"); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             PyObject *sysdict = interp->sysdict; | 
					
						
							|  |  |  |             if (sysdict == NULL) { | 
					
						
							|  |  |  |                 Py_DECREF(path0); | 
					
						
							|  |  |  |                 return _PyStatus_ERR("can't initialize sys.path[0]"); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             PyObject *sys_path = PyDict_GetItemWithError(sysdict, &_Py_ID(path)); | 
					
						
							|  |  |  |             if (sys_path == NULL) { | 
					
						
							|  |  |  |                 Py_DECREF(path0); | 
					
						
							|  |  |  |                 return _PyStatus_ERR("can't initialize sys.path[0]"); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             int res = PyList_Insert(sys_path, 0, path0); | 
					
						
							|  |  |  |             Py_DECREF(path0); | 
					
						
							|  |  |  |             if (res) { | 
					
						
							|  |  |  |                 return _PyStatus_ERR("can't initialize sys.path[0]"); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-25 06:10:51 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 12:14:34 +00:00
										 |  |  |     interp->dict_state.watchers[0] = &builtins_dict_watcher; | 
					
						
							|  |  |  |     if (PyDict_Watch(0, interp->builtins) != 0) { | 
					
						
							| 
									
										
										
										
											2024-01-25 06:10:51 -05:00
										 |  |  |         return _PyStatus_ERR("failed to set builtin dict watcher"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-06 02:43:30 +01:00
										 |  |  |     assert(!_PyErr_Occurred(tstate)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-16 17:38:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  | /* Update interpreter state based on supplied configuration settings
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * After calling this function, most of the restrictions on the interpreter | 
					
						
							|  |  |  |  * are lifted. The only remaining incomplete settings are those related | 
					
						
							|  |  |  |  * to the main module (sys.argv[0], __main__ metadata) | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Calling this when the interpreter is not initializing, is already | 
					
						
							|  |  |  |  * initialized or without a valid current thread state is a fatal error. | 
					
						
							|  |  |  |  * Other errors should be reported as normal Python exceptions with a | 
					
						
							|  |  |  |  * non-zero return code. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static PyStatus | 
					
						
							|  |  |  | pyinit_main(PyThreadState *tstate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyInterpreterState *interp = tstate->interp; | 
					
						
							|  |  |  |     if (!interp->runtime->core_initialized) { | 
					
						
							|  |  |  |         return _PyStatus_ERR("runtime core not initialized"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (interp->runtime->initialized) { | 
					
						
							| 
									
										
										
										
											2020-11-04 17:34:34 +01:00
										 |  |  |         return pyinit_main_reconfigure(tstate); | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyStatus status = init_interp_main(tstate); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return _PyStatus_OK(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | PyStatus | 
					
						
							|  |  |  | Py_InitializeFromConfig(const PyConfig *config) | 
					
						
							| 
									
										
										
										
											2017-05-23 21:46:51 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |     if (config == NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_ERR("initialization config is NULL"); | 
					
						
							| 
									
										
										
										
											2019-05-20 11:02:00 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyStatus status; | 
					
						
							| 
									
										
										
										
											2019-04-24 18:23:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = _PyRuntime_Initialize(); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-04-24 18:23:53 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     _PyRuntimeState *runtime = &_PyRuntime; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |     PyThreadState *tstate = NULL; | 
					
						
							|  |  |  |     status = pyinit_core(runtime, config, &tstate); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-04-13 03:04:28 +02:00
										 |  |  |     config = _PyInterpreterState_GetConfig(tstate->interp); | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-16 17:38:16 +02:00
										 |  |  |     if (config->_init_main) { | 
					
						
							| 
									
										
										
										
											2019-11-20 02:27:56 +01:00
										 |  |  |         status = pyinit_main(tstate); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |             return status; | 
					
						
							| 
									
										
										
										
											2019-03-27 02:04:16 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-27 02:04:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2019-03-27 13:40:14 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | void | 
					
						
							|  |  |  | Py_InitializeEx(int install_sigs) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyStatus status; | 
					
						
							| 
									
										
										
										
											2019-04-24 18:23:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = _PyRuntime_Initialize(); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         Py_ExitStatusException(status); | 
					
						
							| 
									
										
										
										
											2019-04-24 18:23:53 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     _PyRuntimeState *runtime = &_PyRuntime; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (runtime->initialized) { | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  |         /* bpo-33932: Calling Py_Initialize() twice does nothing. */ | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyConfig config; | 
					
						
							| 
									
										
										
										
											2019-10-01 12:06:16 +02:00
										 |  |  |     _PyConfig_InitCompatConfig(&config); | 
					
						
							| 
									
										
										
										
											2019-09-28 04:28:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  |     config.install_signal_handlers = install_sigs; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = Py_InitializeFromConfig(&config); | 
					
						
							| 
									
										
										
										
											2022-10-30 22:01:30 +10:00
										 |  |  |     PyConfig_Clear(&config); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         Py_ExitStatusException(status); | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | Py_Initialize(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Py_InitializeEx(1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-04 17:34:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | PyStatus | 
					
						
							|  |  |  | _Py_InitializeMain(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyStatus status = _PyRuntime_Initialize(); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-05-04 16:21:01 +02:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2020-11-04 17:34:34 +01:00
										 |  |  |     return pyinit_main(tstate); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  | static void | 
					
						
							|  |  |  | finalize_modules_delete_special(PyThreadState *tstate, int verbose) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // List of names to clear in sys
 | 
					
						
							|  |  |  |     static const char * const sys_deletes[] = { | 
					
						
							| 
									
										
										
										
											2023-03-18 11:47:11 +00:00
										 |  |  |         "path", "argv", "ps1", "ps2", "last_exc", | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |         "last_type", "last_value", "last_traceback", | 
					
						
							|  |  |  |         "__interactivehook__", | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  |         // path_hooks and path_importer_cache are cleared
 | 
					
						
							|  |  |  |         // by _PyImport_FiniExternal().
 | 
					
						
							|  |  |  |         // XXX Clear meta_path in _PyImport_FiniCore().
 | 
					
						
							|  |  |  |         "meta_path", | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |         NULL | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static const char * const sys_files[] = { | 
					
						
							|  |  |  |         "stdin", "__stdin__", | 
					
						
							|  |  |  |         "stdout", "__stdout__", | 
					
						
							|  |  |  |         "stderr", "__stderr__", | 
					
						
							|  |  |  |         NULL | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyInterpreterState *interp = tstate->interp; | 
					
						
							|  |  |  |     if (verbose) { | 
					
						
							|  |  |  |         PySys_WriteStderr("# clear builtins._\n"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (PyDict_SetItemString(interp->builtins, "_", Py_None) < 0) { | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |         PyErr_FormatUnraisable("Exception ignored on setting builtin variable _"); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const char * const *p; | 
					
						
							|  |  |  |     for (p = sys_deletes; *p != NULL; p++) { | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  |         if (_PySys_ClearAttrString(interp, *p, verbose) < 0) { | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |             PyErr_FormatUnraisable("Exception ignored on clearing sys.%s", *p); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     for (p = sys_files; *p != NULL; p+=2) { | 
					
						
							|  |  |  |         const char *name = p[0]; | 
					
						
							|  |  |  |         const char *orig_name = p[1]; | 
					
						
							|  |  |  |         if (verbose) { | 
					
						
							|  |  |  |             PySys_WriteStderr("# restore sys.%s\n", name); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-08-23 22:59:00 +02:00
										 |  |  |         PyObject *value; | 
					
						
							|  |  |  |         if (PyDict_GetItemStringRef(interp->sysdict, orig_name, &value) < 0) { | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |             PyErr_FormatUnraisable("Exception ignored on restoring sys.%s", name); | 
					
						
							| 
									
										
										
										
											2023-08-23 22:59:00 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |         if (value == NULL) { | 
					
						
							| 
									
										
										
										
											2023-08-23 22:59:00 +02:00
										 |  |  |             value = Py_NewRef(Py_None); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (PyDict_SetItemString(interp->sysdict, name, value) < 0) { | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |             PyErr_FormatUnraisable("Exception ignored on restoring sys.%s", name); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-08-23 22:59:00 +02:00
										 |  |  |         Py_DECREF(value); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject* | 
					
						
							|  |  |  | finalize_remove_modules(PyObject *modules, int verbose) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *weaklist = PyList_New(0); | 
					
						
							|  |  |  |     if (weaklist == NULL) { | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |         PyErr_FormatUnraisable("Exception ignored on removing modules"); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define STORE_MODULE_WEAKREF(name, mod) \
 | 
					
						
							|  |  |  |         if (weaklist != NULL) { \ | 
					
						
							|  |  |  |             PyObject *wr = PyWeakref_NewRef(mod, NULL); \ | 
					
						
							|  |  |  |             if (wr) { \ | 
					
						
							|  |  |  |                 PyObject *tup = PyTuple_Pack(2, name, wr); \ | 
					
						
							|  |  |  |                 if (!tup || PyList_Append(weaklist, tup) < 0) { \ | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |                     PyErr_FormatUnraisable("Exception ignored on removing modules"); \ | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |                 } \ | 
					
						
							|  |  |  |                 Py_XDECREF(tup); \ | 
					
						
							|  |  |  |                 Py_DECREF(wr); \ | 
					
						
							|  |  |  |             } \ | 
					
						
							|  |  |  |             else { \ | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |                 PyErr_FormatUnraisable("Exception ignored on removing modules"); \ | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |             } \ | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define CLEAR_MODULE(name, mod) \
 | 
					
						
							|  |  |  |         if (PyModule_Check(mod)) { \ | 
					
						
							|  |  |  |             if (verbose && PyUnicode_Check(name)) { \ | 
					
						
							|  |  |  |                 PySys_FormatStderr("# cleanup[2] removing %U\n", name); \ | 
					
						
							|  |  |  |             } \ | 
					
						
							|  |  |  |             STORE_MODULE_WEAKREF(name, mod); \ | 
					
						
							|  |  |  |             if (PyObject_SetItem(modules, name, Py_None) < 0) { \ | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |                 PyErr_FormatUnraisable("Exception ignored on removing modules"); \ | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |             } \ | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (PyDict_CheckExact(modules)) { | 
					
						
							|  |  |  |         Py_ssize_t pos = 0; | 
					
						
							|  |  |  |         PyObject *key, *value; | 
					
						
							|  |  |  |         while (PyDict_Next(modules, &pos, &key, &value)) { | 
					
						
							|  |  |  |             CLEAR_MODULE(key, value); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         PyObject *iterator = PyObject_GetIter(modules); | 
					
						
							|  |  |  |         if (iterator == NULL) { | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |             PyErr_FormatUnraisable("Exception ignored on removing modules"); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |             PyObject *key; | 
					
						
							|  |  |  |             while ((key = PyIter_Next(iterator))) { | 
					
						
							|  |  |  |                 PyObject *value = PyObject_GetItem(modules, key); | 
					
						
							|  |  |  |                 if (value == NULL) { | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |                     PyErr_FormatUnraisable("Exception ignored on removing modules"); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |                     continue; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 CLEAR_MODULE(key, value); | 
					
						
							|  |  |  |                 Py_DECREF(value); | 
					
						
							|  |  |  |                 Py_DECREF(key); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (PyErr_Occurred()) { | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |                 PyErr_FormatUnraisable("Exception ignored on removing modules"); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |             Py_DECREF(iterator); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #undef CLEAR_MODULE
 | 
					
						
							|  |  |  | #undef STORE_MODULE_WEAKREF
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return weaklist; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | finalize_clear_modules_dict(PyObject *modules) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (PyDict_CheckExact(modules)) { | 
					
						
							|  |  |  |         PyDict_Clear(modules); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2022-02-08 13:39:07 -07:00
										 |  |  |         if (PyObject_CallMethodNoArgs(modules, &_Py_ID(clear)) == NULL) { | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |             PyErr_FormatUnraisable("Exception ignored on clearing sys.modules"); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | finalize_restore_builtins(PyThreadState *tstate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyInterpreterState *interp = tstate->interp; | 
					
						
							|  |  |  |     PyObject *dict = PyDict_Copy(interp->builtins); | 
					
						
							|  |  |  |     if (dict == NULL) { | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |         PyErr_FormatUnraisable("Exception ignored on restoring builtins"); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     PyDict_Clear(interp->builtins); | 
					
						
							|  |  |  |     if (PyDict_Update(interp->builtins, interp->builtins_copy)) { | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |         PyErr_FormatUnraisable("Exception ignored on restoring builtins"); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     Py_XDECREF(dict); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | finalize_modules_clear_weaklist(PyInterpreterState *interp, | 
					
						
							|  |  |  |                                 PyObject *weaklist, int verbose) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // First clear modules imported later
 | 
					
						
							|  |  |  |     for (Py_ssize_t i = PyList_GET_SIZE(weaklist) - 1; i >= 0; i--) { | 
					
						
							|  |  |  |         PyObject *tup = PyList_GET_ITEM(weaklist, i); | 
					
						
							|  |  |  |         PyObject *name = PyTuple_GET_ITEM(tup, 0); | 
					
						
							| 
									
										
										
										
											2023-06-21 21:50:20 +02:00
										 |  |  |         PyObject *mod = _PyWeakref_GET_REF(PyTuple_GET_ITEM(tup, 1)); | 
					
						
							|  |  |  |         if (mod == NULL) { | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         assert(PyModule_Check(mod)); | 
					
						
							| 
									
										
										
										
											2023-06-21 21:50:20 +02:00
										 |  |  |         PyObject *dict = _PyModule_GetDict(mod);  // borrowed reference
 | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |         if (dict == interp->builtins || dict == interp->sysdict) { | 
					
						
							| 
									
										
										
										
											2023-06-21 21:50:20 +02:00
										 |  |  |             Py_DECREF(mod); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (verbose && PyUnicode_Check(name)) { | 
					
						
							|  |  |  |             PySys_FormatStderr("# cleanup[3] wiping %U\n", name); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         _PyModule_Clear(mod); | 
					
						
							|  |  |  |         Py_DECREF(mod); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | finalize_clear_sys_builtins_dict(PyInterpreterState *interp, int verbose) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // Clear sys dict
 | 
					
						
							|  |  |  |     if (verbose) { | 
					
						
							|  |  |  |         PySys_FormatStderr("# cleanup[3] wiping sys\n"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     _PyModule_ClearDict(interp->sysdict); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Clear builtins dict
 | 
					
						
							|  |  |  |     if (verbose) { | 
					
						
							|  |  |  |         PySys_FormatStderr("# cleanup[3] wiping builtins\n"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     _PyModule_ClearDict(interp->builtins); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Clear modules, as good as we can */ | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  | // XXX Move most of this to import.c.
 | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  | static void | 
					
						
							|  |  |  | finalize_modules(PyThreadState *tstate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyInterpreterState *interp = tstate->interp; | 
					
						
							| 
									
										
										
										
											2024-01-25 06:10:51 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 12:14:34 +00:00
										 |  |  |     // Invalidate all executors and turn off tier 2 optimizer
 | 
					
						
							| 
									
										
										
										
											2024-02-26 12:51:47 -05:00
										 |  |  |     _Py_Executors_InvalidateAll(interp, 0); | 
					
						
							| 
									
										
										
										
											2024-02-13 14:16:37 +00:00
										 |  |  |     _PyOptimizerObject *old = _Py_SetOptimizer(interp, NULL); | 
					
						
							|  |  |  |     Py_XDECREF(old); | 
					
						
							| 
									
										
										
										
											2024-02-02 12:14:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Stop watching __builtin__ modifications
 | 
					
						
							|  |  |  |     PyDict_Unwatch(0, interp->builtins); | 
					
						
							| 
									
										
										
										
											2024-01-25 06:10:51 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  |     PyObject *modules = _PyImport_GetModules(interp); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |     if (modules == NULL) { | 
					
						
							|  |  |  |         // Already done
 | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     int verbose = _PyInterpreterState_GetConfig(interp)->verbose; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Delete some special builtins._ and sys attributes first.  These are
 | 
					
						
							|  |  |  |     // common places where user values hide and people complain when their
 | 
					
						
							|  |  |  |     // destructors fail.  Since the modules containing them are
 | 
					
						
							|  |  |  |     // deleted *last* of all, they would come too late in the normal
 | 
					
						
							|  |  |  |     // destruction order.  Sigh.
 | 
					
						
							|  |  |  |     //
 | 
					
						
							|  |  |  |     // XXX Perhaps these precautions are obsolete. Who knows?
 | 
					
						
							|  |  |  |     finalize_modules_delete_special(tstate, verbose); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Remove all modules from sys.modules, hoping that garbage collection
 | 
					
						
							|  |  |  |     // can reclaim most of them: set all sys.modules values to None.
 | 
					
						
							|  |  |  |     //
 | 
					
						
							|  |  |  |     // We prepare a list which will receive (name, weakref) tuples of
 | 
					
						
							|  |  |  |     // modules when they are removed from sys.modules.  The name is used
 | 
					
						
							|  |  |  |     // for diagnosis messages (in verbose mode), while the weakref helps
 | 
					
						
							|  |  |  |     // detect those modules which have been held alive.
 | 
					
						
							|  |  |  |     PyObject *weaklist = finalize_remove_modules(modules, verbose); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Clear the modules dict
 | 
					
						
							|  |  |  |     finalize_clear_modules_dict(modules); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Restore the original builtins dict, to ensure that any
 | 
					
						
							|  |  |  |     // user data gets cleared.
 | 
					
						
							|  |  |  |     finalize_restore_builtins(tstate); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Collect garbage
 | 
					
						
							|  |  |  |     _PyGC_CollectNoFail(tstate); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Dump GC stats before it's too late, since it uses the warnings
 | 
					
						
							|  |  |  |     // machinery.
 | 
					
						
							| 
									
										
										
										
											2021-02-19 15:10:45 +01:00
										 |  |  |     _PyGC_DumpShutdownStats(interp); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (weaklist != NULL) { | 
					
						
							|  |  |  |         // Now, if there are any modules left alive, clear their globals to
 | 
					
						
							|  |  |  |         // minimize potential leaks.  All C extension modules actually end
 | 
					
						
							|  |  |  |         // up here, since they are kept alive in the interpreter state.
 | 
					
						
							|  |  |  |         //
 | 
					
						
							|  |  |  |         // The special treatment of "builtins" here is because even
 | 
					
						
							|  |  |  |         // when it's not referenced as a module, its dictionary is
 | 
					
						
							|  |  |  |         // referenced by almost every module's __builtins__.  Since
 | 
					
						
							|  |  |  |         // deleting a module clears its dictionary (even if there are
 | 
					
						
							|  |  |  |         // references left to it), we need to delete the "builtins"
 | 
					
						
							|  |  |  |         // module last.  Likewise, we don't delete sys until the very
 | 
					
						
							|  |  |  |         // end because it is implicitly referenced (e.g. by print).
 | 
					
						
							|  |  |  |         //
 | 
					
						
							|  |  |  |         // Since dict is ordered in CPython 3.6+, modules are saved in
 | 
					
						
							|  |  |  |         // importing order.  First clear modules imported later.
 | 
					
						
							|  |  |  |         finalize_modules_clear_weaklist(interp, weaklist, verbose); | 
					
						
							|  |  |  |         Py_DECREF(weaklist); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Clear sys and builtins modules dict
 | 
					
						
							|  |  |  |     finalize_clear_sys_builtins_dict(interp, verbose); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Clear module dict copies stored in the interpreter state:
 | 
					
						
							|  |  |  |     // clear PyInterpreterState.modules_by_index and
 | 
					
						
							|  |  |  |     // clear PyModuleDef.m_base.m_copy (of extensions not using the multi-phase
 | 
					
						
							|  |  |  |     // initialization API)
 | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  |     _PyImport_ClearModulesByIndex(interp); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Clear and delete the modules directory.  Actual modules will
 | 
					
						
							|  |  |  |     // still be there only if imported during the execution of some
 | 
					
						
							|  |  |  |     // destructor.
 | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  |     _PyImport_ClearModules(interp); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Collect garbage once more
 | 
					
						
							|  |  |  |     _PyGC_CollectNoFail(tstate); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | /* Flush stdout and stderr */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | file_is_closed(PyObject *fobj) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int r; | 
					
						
							|  |  |  |     PyObject *tmp = PyObject_GetAttrString(fobj, "closed"); | 
					
						
							|  |  |  |     if (tmp == NULL) { | 
					
						
							|  |  |  |         PyErr_Clear(); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     r = PyObject_IsTrue(tmp); | 
					
						
							|  |  |  |     Py_DECREF(tmp); | 
					
						
							|  |  |  |     if (r < 0) | 
					
						
							|  |  |  |         PyErr_Clear(); | 
					
						
							|  |  |  |     return r > 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-30 03:18:29 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | flush_std_files(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-02-08 13:39:07 -07:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							|  |  |  |     PyObject *fout = _PySys_GetAttr(tstate, &_Py_ID(stdout)); | 
					
						
							|  |  |  |     PyObject *ferr = _PySys_GetAttr(tstate, &_Py_ID(stderr)); | 
					
						
							| 
									
										
										
										
											2015-11-30 03:18:29 +00:00
										 |  |  |     int status = 0; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { | 
					
						
							| 
									
										
										
										
											2023-09-23 09:35:30 +03:00
										 |  |  |         if (_PyFile_Flush(fout) < 0) { | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |             PyErr_FormatUnraisable("Exception ignored on flushing sys.stdout"); | 
					
						
							| 
									
										
										
										
											2015-11-30 03:18:29 +00:00
										 |  |  |             status = -1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) { | 
					
						
							| 
									
										
										
										
											2023-09-23 09:35:30 +03:00
										 |  |  |         if (_PyFile_Flush(ferr) < 0) { | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |             PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											2015-11-30 03:18:29 +00:00
										 |  |  |             status = -1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-11-30 03:18:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return status; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Undo the effect of Py_Initialize().
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Beware: if multiple interpreter and/or thread states exist, these | 
					
						
							|  |  |  |    are not wiped out; only the current thread and interpreter state | 
					
						
							|  |  |  |    are deleted.  But since everything else is deleted, those other | 
					
						
							|  |  |  |    interpreter and thread states should no longer be used. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    (XXX We should do better, e.g. wipe out all interpreters and | 
					
						
							|  |  |  |    threads.) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Locking: as above. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 10:38:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2021-02-19 15:10:45 +01:00
										 |  |  | finalize_interp_types(PyInterpreterState *interp) | 
					
						
							| 
									
										
										
										
											2019-11-20 10:38:34 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-01-22 22:55:39 +01:00
										 |  |  |     _PyUnicode_FiniTypes(interp); | 
					
						
							| 
									
										
										
										
											2023-05-01 19:36:00 -06:00
										 |  |  |     _PySys_FiniTypes(interp); | 
					
						
							| 
									
										
										
										
											2023-12-12 08:24:31 -07:00
										 |  |  |     _PyXI_FiniTypes(interp); | 
					
						
							| 
									
										
										
										
											2021-02-19 15:10:45 +01:00
										 |  |  |     _PyExc_Fini(interp); | 
					
						
							| 
									
										
										
										
											2022-01-21 01:42:25 +01:00
										 |  |  |     _PyFloat_FiniType(interp); | 
					
						
							|  |  |  |     _PyLong_FiniTypes(interp); | 
					
						
							|  |  |  |     _PyThread_FiniType(interp); | 
					
						
							| 
									
										
										
										
											2023-04-24 17:23:57 -06:00
										 |  |  |     // XXX fini collections module static types (_PyStaticType_Dealloc())
 | 
					
						
							|  |  |  |     // XXX fini IO module static types (_PyStaticType_Dealloc())
 | 
					
						
							| 
									
										
										
										
											2022-01-21 01:42:25 +01:00
										 |  |  |     _PyErr_FiniTypes(interp); | 
					
						
							| 
									
										
										
										
											2022-01-21 13:06:34 +01:00
										 |  |  |     _PyTypes_FiniTypes(interp); | 
					
						
							| 
									
										
										
										
											2022-01-21 01:42:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												gh-94673: Always Finalize Static Builtin Types (#95153)
Static builtin types are finalized by calling _PyStaticType_Dealloc().  Before this change, we were skipping finalizing such a type if it still had subtypes (i.e. its tp_subclasses hadn't been cleared yet).  The problem is that types hold several heap objects, which leak if we skip the type's finalization.  This change addresses that.
For context, there's an old comment (from e9e3eab0b86) that says the following:
   // If a type still has subtypes, it cannot be deallocated.
   // A subtype can inherit attributes and methods of its parent type,
   // and a type must no longer be used once it's deallocated.
However, it isn't clear that is actually still true.  Clearing tp_dict should mean it isn't a problem.
Furthermore, the only subtypes that might still be around come from extension modules that didn't clean them up when unloaded (i.e. extensions that do not implement multi-phase initialization, AKA PEP 489).  Those objects are already leaking, so this change doesn't change anything in that regard.  Instead, this change means more objects gets cleaned up that before.
											
										 
											2022-07-25 14:23:41 -06:00
										 |  |  |     _PyTypes_Fini(interp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-26 02:58:33 +01:00
										 |  |  |     // Call _PyUnicode_ClearInterned() before _PyDict_Fini() since it uses
 | 
					
						
							|  |  |  |     // a dict internally.
 | 
					
						
							| 
									
										
										
										
											2021-02-19 15:10:45 +01:00
										 |  |  |     _PyUnicode_ClearInterned(interp); | 
					
						
							| 
									
										
										
										
											2020-06-08 01:22:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 15:10:45 +01:00
										 |  |  |     _PyUnicode_Fini(interp); | 
					
						
							| 
									
										
										
										
											2024-01-10 08:04:41 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-10 09:57:04 +09:00
										 |  |  | #ifndef Py_GIL_DISABLED
 | 
					
						
							|  |  |  |     // With Py_GIL_DISABLED:
 | 
					
						
							|  |  |  |     // the freelists for the current thread state have already been cleared.
 | 
					
						
							| 
									
										
										
										
											2024-02-14 09:32:51 +09:00
										 |  |  |     struct _Py_object_freelists *freelists = _Py_object_freelists_GET(); | 
					
						
							|  |  |  |     _PyObject_ClearFreeLists(freelists, 1); | 
					
						
							| 
									
										
										
										
											2024-02-10 09:57:04 +09:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2024-01-10 08:04:41 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-25 23:13:59 +05:30
										 |  |  | #ifdef Py_DEBUG
 | 
					
						
							| 
									
										
										
										
											2022-11-11 14:24:18 -07:00
										 |  |  |     _PyStaticObjects_CheckRefcnt(interp); | 
					
						
							| 
									
										
										
										
											2022-07-25 23:13:59 +05:30
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-11-20 10:38:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2019-11-20 18:39:12 +01:00
										 |  |  | finalize_interp_clear(PyThreadState *tstate) | 
					
						
							| 
									
										
										
										
											2019-11-20 10:38:34 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-19 13:33:31 +01:00
										 |  |  |     int is_main_interp = _Py_IsMainInterpreter(tstate->interp); | 
					
						
							| 
									
										
										
										
											2019-11-20 18:39:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-01 17:36:40 -06:00
										 |  |  |     _PyXI_Fini(tstate->interp); | 
					
						
							| 
									
										
										
										
											2021-10-23 00:13:46 +01:00
										 |  |  |     _PyExc_ClearExceptionGroupType(tstate->interp); | 
					
						
							| 
									
										
										
										
											2023-05-15 20:36:23 -07:00
										 |  |  |     _Py_clear_generic_types(tstate->interp); | 
					
						
							| 
									
										
										
										
											2023-12-07 08:47:55 -05:00
										 |  |  |     _PyDtoa_Fini(tstate->interp); | 
					
						
							| 
									
										
										
										
											2021-10-23 00:13:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 10:38:34 +01:00
										 |  |  |     /* Clear interpreter state and all thread states */ | 
					
						
							| 
									
										
										
										
											2020-10-30 22:51:02 +01:00
										 |  |  |     _PyInterpreterState_Clear(tstate); | 
					
						
							| 
									
										
										
										
											2019-12-04 11:51:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-04 05:06:46 +08:00
										 |  |  |     /* Clear all loghooks */ | 
					
						
							|  |  |  |     /* Both _PySys_Audit function and users still need PyObject, such as tuple.
 | 
					
						
							|  |  |  |        Call _PySys_ClearAuditHooks when PyObject available. */ | 
					
						
							|  |  |  |     if (is_main_interp) { | 
					
						
							|  |  |  |         _PySys_ClearAuditHooks(tstate); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 10:38:34 +01:00
										 |  |  |     if (is_main_interp) { | 
					
						
							| 
									
										
										
										
											2020-06-08 01:22:36 +02:00
										 |  |  |         _Py_HashRandomization_Fini(); | 
					
						
							|  |  |  |         _PyArg_Fini(); | 
					
						
							|  |  |  |         _Py_ClearFileSystemEncoding(); | 
					
						
							| 
									
										
										
										
											2022-08-30 18:11:18 +01:00
										 |  |  |         _PyPerfTrampoline_Fini(); | 
					
						
							| 
									
										
										
										
											2023-12-01 13:20:51 +00:00
										 |  |  |         _PyPerfTrampoline_FreeArenas(); | 
					
						
							| 
									
										
										
										
											2020-06-08 01:22:36 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-11-20 10:38:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 15:10:45 +01:00
										 |  |  |     finalize_interp_types(tstate->interp); | 
					
						
							| 
									
										
										
										
											2023-12-26 11:53:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-20 13:04:37 -05:00
										 |  |  |     /* Free any delayed free requests immediately */ | 
					
						
							|  |  |  |     _PyMem_FiniDelayed(tstate->interp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-26 11:53:20 -05:00
										 |  |  |     /* finalize_interp_types may allocate Python objects so we may need to
 | 
					
						
							|  |  |  |        abandon mimalloc segments again */ | 
					
						
							|  |  |  |     _PyThreadState_ClearMimallocHeaps(tstate); | 
					
						
							| 
									
										
										
										
											2019-11-20 10:38:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2021-02-19 15:10:45 +01:00
										 |  |  | finalize_interp_delete(PyInterpreterState *interp) | 
					
						
							| 
									
										
										
										
											2019-11-20 10:38:34 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-19 16:04:14 -07:00
										 |  |  |     /* Cleanup auto-thread-state */ | 
					
						
							|  |  |  |     _PyGILState_Fini(interp); | 
					
						
							| 
									
										
										
										
											2019-11-20 10:38:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-08 17:54:59 +02:00
										 |  |  |     /* We can't call _PyEval_FiniGIL() here because destroying the GIL lock can
 | 
					
						
							|  |  |  |        fail when it is being awaited by another running daemon thread (see | 
					
						
							|  |  |  |        bpo-9901). Instead pycore_create_interpreter() destroys the previously | 
					
						
							|  |  |  |        created GIL, which ensures that Py_Initialize / Py_FinalizeEx can be | 
					
						
							|  |  |  |        called multiple times. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 15:10:45 +01:00
										 |  |  |     PyInterpreterState_Delete(interp); | 
					
						
							| 
									
										
										
										
											2019-11-20 10:38:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-30 03:18:29 +00:00
										 |  |  | int | 
					
						
							|  |  |  | Py_FinalizeEx(void) | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-11-30 03:18:29 +00:00
										 |  |  |     int status = 0; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-24 17:24:01 +02:00
										 |  |  |     _PyRuntimeState *runtime = &_PyRuntime; | 
					
						
							|  |  |  |     if (!runtime->initialized) { | 
					
						
							| 
									
										
										
										
											2015-11-30 03:18:29 +00:00
										 |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-04-24 17:24:01 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |     /* Get current thread state and interpreter pointer */ | 
					
						
							| 
									
										
										
										
											2023-05-04 16:21:01 +02:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2023-01-30 12:07:48 -07:00
										 |  |  |     // XXX assert(_Py_IsMainInterpreter(tstate->interp));
 | 
					
						
							|  |  |  |     // XXX assert(_Py_IsMainThread());
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Block some operations.
 | 
					
						
							|  |  |  |     tstate->interp->finalizing = 1; | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 15:47:51 -06:00
										 |  |  |     // Wrap up existing "threading"-module-created, non-daemon threads.
 | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |     wait_for_thread_shutdown(tstate); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 15:47:51 -06:00
										 |  |  |     // Make any remaining pending calls.
 | 
					
						
							| 
									
										
										
										
											2020-01-13 18:46:59 +01:00
										 |  |  |     _Py_FinishPendingCalls(tstate); | 
					
						
							| 
									
										
										
										
											2019-06-03 18:14:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     /* The interpreter is still entirely intact at this point, and the
 | 
					
						
							|  |  |  |      * exit funcs may be relying on that.  In particular, if some thread | 
					
						
							|  |  |  |      * or exit func is still waiting to do an import, the import machinery | 
					
						
							|  |  |  |      * expects Py_IsInitialized() to return true.  So don't say the | 
					
						
							| 
									
										
										
										
											2019-03-15 15:47:51 -06:00
										 |  |  |      * runtime is uninitialized until after the exit funcs have run. | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |      * Note that Threading.py uses an exit func to do a join on all the | 
					
						
							|  |  |  |      * threads created thru it, so this also protects pending imports in | 
					
						
							|  |  |  |      * the threads created via Threading. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 15:10:45 +01:00
										 |  |  |     _PyAtExit_Call(tstate->interp); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 01:46:02 +01:00
										 |  |  |     /* Copy the core config, PyInterpreterState_Delete() free
 | 
					
						
							|  |  |  |        the core config memory */ | 
					
						
							| 
									
										
										
										
											2017-12-19 11:35:58 +01:00
										 |  |  | #ifdef Py_REF_DEBUG
 | 
					
						
							| 
									
										
										
										
											2020-11-18 16:38:53 +01:00
										 |  |  |     int show_ref_count = tstate->interp->config.show_ref_count; | 
					
						
							| 
									
										
										
										
											2017-12-19 11:35:58 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef Py_TRACE_REFS
 | 
					
						
							| 
									
										
										
										
											2020-11-18 16:38:53 +01:00
										 |  |  |     int dump_refs = tstate->interp->config.dump_refs; | 
					
						
							| 
									
										
										
										
											2021-08-17 15:52:50 +00:00
										 |  |  |     wchar_t *dump_refs_file = tstate->interp->config.dump_refs_file; | 
					
						
							| 
									
										
										
										
											2017-12-19 11:35:58 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef WITH_PYMALLOC
 | 
					
						
							| 
									
										
										
										
											2020-11-18 16:38:53 +01:00
										 |  |  |     int malloc_stats = tstate->interp->config.malloc_stats; | 
					
						
							| 
									
										
										
										
											2017-12-19 11:35:58 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-12-06 17:26:10 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-08 11:57:45 +01:00
										 |  |  |     /* Remaining daemon threads will automatically exit
 | 
					
						
							|  |  |  |        when they attempt to take the GIL (ex: PyEval_RestoreThread()). */ | 
					
						
							| 
									
										
										
										
											2023-05-15 13:59:26 -06:00
										 |  |  |     _PyInterpreterState_SetFinalizing(tstate->interp, tstate); | 
					
						
							| 
									
										
										
										
											2020-03-07 00:24:23 +01:00
										 |  |  |     _PyRuntimeState_SetFinalizing(runtime, tstate); | 
					
						
							| 
									
										
										
										
											2019-04-24 17:24:01 +02:00
										 |  |  |     runtime->initialized = 0; | 
					
						
							|  |  |  |     runtime->core_initialized = 0; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  |     // XXX Call something like _PyImport_Disable() here?
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-09 23:37:49 +01:00
										 |  |  |     /* Destroy the state of all threads of the interpreter, except of the
 | 
					
						
							|  |  |  |        current thread. In practice, only daemon threads should still be alive, | 
					
						
							|  |  |  |        except if wait_for_thread_shutdown() has been cancelled by CTRL+C. | 
					
						
							|  |  |  |        Clear frames of other threads to call objects destructors. Destructors | 
					
						
							|  |  |  |        will be called in the current Python thread. Since | 
					
						
							|  |  |  |        _PyRuntimeState_SetFinalizing() has been called, no other Python thread | 
					
						
							|  |  |  |        can take the GIL at this point: if they try, they will exit | 
					
						
							|  |  |  |        immediately. */ | 
					
						
							| 
									
										
										
										
											2023-01-30 12:07:48 -07:00
										 |  |  |     _PyThreadState_DeleteExcept(tstate); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* At this point no Python code should be running at all.
 | 
					
						
							|  |  |  |        The only thread state left should be the main thread of the main | 
					
						
							|  |  |  |        interpreter (AKA tstate), in which this code is running right now. | 
					
						
							|  |  |  |        There may be other OS threads running but none of them will have | 
					
						
							|  |  |  |        thread states associated with them, nor will be able to create | 
					
						
							|  |  |  |        new thread states. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        Thus tstate is the only possible thread state from here on out. | 
					
						
							|  |  |  |        It may still be used during finalization to run Python code as | 
					
						
							|  |  |  |        needed or provide runtime state (e.g. sys.modules) but that will | 
					
						
							|  |  |  |        happen sparingly.  Furthermore, the order of finalization aims | 
					
						
							|  |  |  |        to not need a thread (or interpreter) state as soon as possible. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     // XXX Make sure we are preventing the creating of any new thread states
 | 
					
						
							|  |  |  |     // (or interpreters).
 | 
					
						
							| 
									
										
										
										
											2020-03-09 23:37:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-24 13:46:18 +01:00
										 |  |  |     /* Flush sys.stdout and sys.stderr */ | 
					
						
							| 
									
										
										
										
											2015-11-30 03:18:29 +00:00
										 |  |  |     if (flush_std_files() < 0) { | 
					
						
							|  |  |  |         status = -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Disable signal handling */ | 
					
						
							| 
									
										
										
										
											2020-11-17 16:22:23 +01:00
										 |  |  |     _PySignal_Fini(); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Collect garbage.  This may call finalizers; it's nice to call these
 | 
					
						
							|  |  |  |      * before all modules are destroyed. | 
					
						
							|  |  |  |      * XXX If a __del__ or weakref callback is triggered here, and tries to | 
					
						
							|  |  |  |      * XXX import a module, bad things can happen, because Python no | 
					
						
							|  |  |  |      * XXX longer believes it's initialized. | 
					
						
							|  |  |  |      * XXX     Fatal Python error: Interpreter not initialized (version mismatch?) | 
					
						
							|  |  |  |      * XXX is easy to provoke that way.  I've also seen, e.g., | 
					
						
							|  |  |  |      * XXX     Exception exceptions.ImportError: 'No module named sha' | 
					
						
							|  |  |  |      * XXX         in <function callback at 0x008F5718> ignored | 
					
						
							|  |  |  |      * XXX but I'm unclear on exactly how that one happens.  In any case, | 
					
						
							|  |  |  |      * XXX I haven't seen a real-life report of either of these. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-10-30 17:00:00 +01:00
										 |  |  |     PyGC_Collect(); | 
					
						
							| 
									
										
										
										
											2017-09-14 00:35:58 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     /* Destroy all modules */ | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  |     _PyImport_FiniExternal(tstate->interp); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |     finalize_modules(tstate); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-03 21:30:58 +09:00
										 |  |  |     /* Print debug stats if any */ | 
					
						
							|  |  |  |     _PyEval_Fini(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-24 13:46:18 +01:00
										 |  |  |     /* Flush sys.stdout and sys.stderr (again, in case more was printed) */ | 
					
						
							| 
									
										
										
										
											2015-11-30 03:18:29 +00:00
										 |  |  |     if (flush_std_files() < 0) { | 
					
						
							|  |  |  |         status = -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Collect final garbage.  This disposes of cycles created by
 | 
					
						
							|  |  |  |      * class definitions, for example. | 
					
						
							|  |  |  |      * XXX This is disabled because it caused too many problems.  If | 
					
						
							|  |  |  |      * XXX a __del__ or weakref callback triggers here, Python code has | 
					
						
							|  |  |  |      * XXX a hard time running, because even the sys module has been | 
					
						
							|  |  |  |      * XXX cleared out (sys.stdout is gone, sys.excepthook is gone, etc). | 
					
						
							|  |  |  |      * XXX One symptom is a sequence of information-free messages | 
					
						
							|  |  |  |      * XXX coming from threads (if a __del__ or callback is invoked, | 
					
						
							|  |  |  |      * XXX other threads can execute too, and any exception they encounter | 
					
						
							|  |  |  |      * XXX triggers a comedy of errors as subsystem after subsystem | 
					
						
							|  |  |  |      * XXX fails to find what it *expects* to find in sys to help report | 
					
						
							|  |  |  |      * XXX the exception and consequent unexpected failures).  I've also | 
					
						
							|  |  |  |      * XXX seen segfaults then, after adding print statements to the | 
					
						
							|  |  |  |      * XXX Python code getting called. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2016-09-09 21:47:46 -07:00
										 |  |  |     _PyGC_CollectIfEnabled(); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Disable tracemalloc after all Python objects have been destroyed,
 | 
					
						
							|  |  |  |        so it is possible to use tracemalloc in objects destructor. */ | 
					
						
							|  |  |  |     _PyTraceMalloc_Fini(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  |     /* Finalize any remaining import state */ | 
					
						
							|  |  |  |     // XXX Move these up to where finalize_modules() is currently.
 | 
					
						
							|  |  |  |     _PyImport_FiniCore(tstate->interp); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     _PyImport_Fini(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* unload faulthandler module */ | 
					
						
							|  |  |  |     _PyFaulthandler_Fini(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* dump hash stats */ | 
					
						
							|  |  |  |     _PyHash_Fini(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef Py_TRACE_REFS
 | 
					
						
							|  |  |  |     /* Display all objects still alive -- this can invoke arbitrary
 | 
					
						
							|  |  |  |      * __repr__ overrides, so requires a mostly-intact interpreter. | 
					
						
							|  |  |  |      * Alas, a lot of stuff may still be alive now that will be cleaned | 
					
						
							|  |  |  |      * up later. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-08-17 15:52:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     FILE *dump_refs_fp = NULL; | 
					
						
							|  |  |  |     if (dump_refs_file != NULL) { | 
					
						
							|  |  |  |         dump_refs_fp = _Py_wfopen(dump_refs_file, L"w"); | 
					
						
							|  |  |  |         if (dump_refs_fp == NULL) { | 
					
						
							|  |  |  |             fprintf(stderr, "PYTHONDUMPREFSFILE: cannot create file: %ls\n", dump_refs_file); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 01:46:02 +01:00
										 |  |  |     if (dump_refs) { | 
					
						
							| 
									
										
										
										
											2023-08-03 13:51:08 -06:00
										 |  |  |         _Py_PrintReferences(tstate->interp, stderr); | 
					
						
							| 
									
										
										
										
											2017-12-06 17:26:10 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-17 15:52:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (dump_refs_fp != NULL) { | 
					
						
							| 
									
										
										
										
											2023-08-03 13:51:08 -06:00
										 |  |  |         _Py_PrintReferences(tstate->interp, dump_refs_fp); | 
					
						
							| 
									
										
										
										
											2021-08-17 15:52:50 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | #endif /* Py_TRACE_REFS */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-30 12:07:48 -07:00
										 |  |  |     /* At this point there's almost no other Python code that will run,
 | 
					
						
							|  |  |  |        nor interpreter state needed.  The only possibility is the | 
					
						
							|  |  |  |        finalizers of the objects stored on tstate (and tstate->interp), | 
					
						
							|  |  |  |        which are triggered via finalize_interp_clear(). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        For now we operate as though none of those finalizers actually | 
					
						
							|  |  |  |        need an operational thread state or interpreter.  In reality, | 
					
						
							|  |  |  |        those finalizers may rely on some part of tstate or | 
					
						
							|  |  |  |        tstate->interp, and/or may raise exceptions | 
					
						
							|  |  |  |        or otherwise fail. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     // XXX Do this sooner during finalization.
 | 
					
						
							|  |  |  |     // XXX Ensure finalizer errors are handled properly.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 18:39:12 +01:00
										 |  |  |     finalize_interp_clear(tstate); | 
					
						
							| 
									
										
										
										
											2022-01-21 13:05:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | #ifdef Py_TRACE_REFS
 | 
					
						
							|  |  |  |     /* Display addresses (& refcnts) of all objects still alive.
 | 
					
						
							|  |  |  |      * An address can be used to find the repr of the object, printed | 
					
						
							| 
									
										
										
										
											2023-08-31 18:33:34 +02:00
										 |  |  |      * above by _Py_PrintReferences. */ | 
					
						
							| 
									
										
										
										
											2017-12-15 01:46:02 +01:00
										 |  |  |     if (dump_refs) { | 
					
						
							| 
									
										
										
										
											2023-08-03 13:51:08 -06:00
										 |  |  |         _Py_PrintReferenceAddresses(tstate->interp, stderr); | 
					
						
							| 
									
										
										
										
											2017-12-06 17:26:10 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-17 15:52:50 +00:00
										 |  |  |     if (dump_refs_fp != NULL) { | 
					
						
							| 
									
										
										
										
											2023-08-03 13:51:08 -06:00
										 |  |  |         _Py_PrintReferenceAddresses(tstate->interp, dump_refs_fp); | 
					
						
							| 
									
										
										
										
											2021-08-17 15:52:50 +00:00
										 |  |  |         fclose(dump_refs_fp); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | #endif /* Py_TRACE_REFS */
 | 
					
						
							| 
									
										
										
										
											2023-08-31 18:33:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     finalize_interp_delete(tstate->interp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef Py_REF_DEBUG
 | 
					
						
							|  |  |  |     if (show_ref_count) { | 
					
						
							|  |  |  |         _PyDebug_PrintTotalRefs(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     _Py_FinalizeRefTotal(runtime); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     _Py_FinalizeAllocatedBlocks(runtime); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 12:04:26 +01:00
										 |  |  | #ifdef WITH_PYMALLOC
 | 
					
						
							| 
									
										
										
										
											2017-12-15 01:46:02 +01:00
										 |  |  |     if (malloc_stats) { | 
					
						
							| 
									
										
										
										
											2017-12-06 17:26:10 +01:00
										 |  |  |         _PyObject_DebugMallocStats(stderr); | 
					
						
							| 
									
										
										
										
											2016-03-14 12:04:26 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-24 17:24:01 +02:00
										 |  |  |     call_ll_exitfuncs(runtime); | 
					
						
							| 
									
										
										
										
											2017-11-25 03:17:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-07 23:51:28 -06:00
										 |  |  |     _PyRuntime_Finalize(); | 
					
						
							| 
									
										
										
										
											2015-11-30 03:18:29 +00:00
										 |  |  |     return status; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | Py_Finalize(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Py_FinalizeEx(); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | /* Create and initialize a new interpreter and thread, and return the
 | 
					
						
							|  |  |  |    new thread.  This requires that Py_Initialize() has been called | 
					
						
							|  |  |  |    first. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Unsuccessful initialization yields a NULL pointer.  Note that *no* | 
					
						
							|  |  |  |    exception information is available even in this case -- the | 
					
						
							|  |  |  |    exception information is held in the thread, and there is no | 
					
						
							|  |  |  |    thread. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Locking: as above. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2023-05-02 21:40:00 -06:00
										 |  |  | new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config) | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyStatus status; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = _PyRuntime_Initialize(); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2019-04-24 18:23:53 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     _PyRuntimeState *runtime = &_PyRuntime; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!runtime->initialized) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_ERR("Py_Initialize must be called first"); | 
					
						
							| 
									
										
										
										
											2017-11-15 18:11:45 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 22:07:55 +01:00
										 |  |  |     /* Issue #10915, #15751: The GIL API doesn't work with multiple
 | 
					
						
							|  |  |  |        interpreters: disable PyGILState_Check(). */ | 
					
						
							| 
									
										
										
										
											2020-04-13 11:45:21 +02:00
										 |  |  |     runtime->gilstate.check_enabled = 0; | 
					
						
							| 
									
										
										
										
											2016-03-14 22:07:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-24 18:23:53 +02:00
										 |  |  |     PyInterpreterState *interp = PyInterpreterState_New(); | 
					
						
							| 
									
										
										
										
											2017-11-15 18:11:45 -08:00
										 |  |  |     if (interp == NULL) { | 
					
						
							|  |  |  |         *tstate_p = NULL; | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2017-11-15 18:11:45 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-12 19:20:21 -05:00
										 |  |  |     // XXX Might new_interpreter() have been called without the GIL held?
 | 
					
						
							| 
									
										
										
										
											2023-10-05 15:46:33 +00:00
										 |  |  |     PyThreadState *save_tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2023-12-12 19:20:21 -05:00
										 |  |  |     PyThreadState *tstate = NULL; | 
					
						
							| 
									
										
										
										
											2023-05-06 15:59:30 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* From this point until the init_interp_create_gil() call,
 | 
					
						
							|  |  |  |        we must not do anything that requires that the GIL be held | 
					
						
							|  |  |  |        (or otherwise exist).  That applies whether or not the new | 
					
						
							|  |  |  |        interpreter has its own GIL (e.g. the main interpreter). */ | 
					
						
							| 
									
										
										
										
											2023-12-12 19:20:21 -05:00
										 |  |  |     if (save_tstate != NULL) { | 
					
						
							|  |  |  |         _PyThreadState_Detach(save_tstate); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-23 21:46:51 -07:00
										 |  |  |     /* Copy the current interpreter config into the new interpreter */ | 
					
						
							| 
									
										
										
										
											2022-10-26 11:16:30 -06:00
										 |  |  |     const PyConfig *src_config; | 
					
						
							| 
									
										
										
										
											2017-05-23 21:46:51 -07:00
										 |  |  |     if (save_tstate != NULL) { | 
					
						
							| 
									
										
										
										
											2022-10-26 11:16:30 -06:00
										 |  |  |         src_config = _PyInterpreterState_GetConfig(save_tstate->interp); | 
					
						
							| 
									
										
										
										
											2020-05-05 20:27:47 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-05-23 21:46:51 -07:00
										 |  |  |         /* No current thread state, copy from the main interpreter */ | 
					
						
							| 
									
										
										
										
											2021-12-07 18:56:06 -07:00
										 |  |  |         PyInterpreterState *main_interp = _PyInterpreterState_Main(); | 
					
						
							| 
									
										
										
										
											2022-10-26 11:16:30 -06:00
										 |  |  |         src_config = _PyInterpreterState_GetConfig(main_interp); | 
					
						
							| 
									
										
										
										
											2017-12-15 01:46:02 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-06 15:59:30 -06:00
										 |  |  |     /* This does not require that the GIL be held. */ | 
					
						
							| 
									
										
										
										
											2022-10-26 11:16:30 -06:00
										 |  |  |     status = _PyConfig_Copy(&interp->config, src_config); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							| 
									
										
										
										
											2019-12-06 02:43:30 +01:00
										 |  |  |         goto error; | 
					
						
							| 
									
										
										
										
											2017-12-15 01:46:02 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-10-26 11:16:30 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-06 15:59:30 -06:00
										 |  |  |     /* This does not require that the GIL be held. */ | 
					
						
							| 
									
										
										
										
											2023-04-24 17:23:57 -06:00
										 |  |  |     status = init_interp_settings(interp, config); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 19:38:14 -08:00
										 |  |  |     // initialize the interp->obmalloc state.  This must be done after
 | 
					
						
							|  |  |  |     // the settings are loaded (so that feature_flags are set) but before
 | 
					
						
							|  |  |  |     // any calls are made to obmalloc functions.
 | 
					
						
							|  |  |  |     if (_PyMem_init_obmalloc(interp) < 0) { | 
					
						
							|  |  |  |         status = _PyStatus_NO_MEMORY(); | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-12 19:20:21 -05:00
										 |  |  |     tstate = _PyThreadState_New(interp, _PyThreadState_WHENCE_INTERP); | 
					
						
							|  |  |  |     if (tstate == NULL) { | 
					
						
							|  |  |  |         status = _PyStatus_NO_MEMORY(); | 
					
						
							| 
									
										
										
										
											2019-12-06 02:43:30 +01:00
										 |  |  |         goto error; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-12-12 19:20:21 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     _PyThreadState_Bind(tstate); | 
					
						
							|  |  |  |     init_interp_create_gil(tstate, config->gil); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-07 13:14:56 -06:00
										 |  |  |     /* No objects have been created yet. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-05 20:16:37 +02:00
										 |  |  |     status = pycore_interp_init(tstate); | 
					
						
							| 
									
										
										
										
											2019-12-06 02:43:30 +01:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         goto error; | 
					
						
							| 
									
										
										
										
											2017-11-15 18:11:45 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-05 20:16:37 +02:00
										 |  |  |     status = init_interp_main(tstate); | 
					
						
							| 
									
										
										
										
											2020-03-19 02:41:21 +01:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							| 
									
										
										
										
											2020-05-05 20:16:37 +02:00
										 |  |  |         goto error; | 
					
						
							| 
									
										
										
										
											2020-03-19 02:41:21 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-15 18:11:45 -08:00
										 |  |  |     *tstate_p = tstate; | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-06 02:43:30 +01:00
										 |  |  | error: | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  |     *tstate_p = NULL; | 
					
						
							| 
									
										
										
										
											2023-12-12 19:20:21 -05:00
										 |  |  |     if (tstate != NULL) { | 
					
						
							|  |  |  |         PyThreadState_Clear(tstate); | 
					
						
							| 
									
										
										
										
											2023-10-05 15:46:33 +00:00
										 |  |  |         _PyThreadState_Detach(tstate); | 
					
						
							| 
									
										
										
										
											2023-12-12 19:20:21 -05:00
										 |  |  |         PyThreadState_Delete(tstate); | 
					
						
							| 
									
										
										
										
											2023-05-06 15:59:30 -06:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-10-05 15:46:33 +00:00
										 |  |  |     if (save_tstate != NULL) { | 
					
						
							|  |  |  |         _PyThreadState_Attach(save_tstate); | 
					
						
							| 
									
										
										
										
											2023-05-06 15:59:30 -06:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     PyInterpreterState_Delete(interp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-22 17:52:42 +01:00
										 |  |  |     return status; | 
					
						
							| 
									
										
										
										
											2017-11-15 18:11:45 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-21 10:49:12 -06:00
										 |  |  | PyStatus | 
					
						
							| 
									
										
										
										
											2023-05-02 21:40:00 -06:00
										 |  |  | Py_NewInterpreterFromConfig(PyThreadState **tstate_p, | 
					
						
							|  |  |  |                             const PyInterpreterConfig *config) | 
					
						
							| 
									
										
										
										
											2017-11-15 18:11:45 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-03-21 10:49:12 -06:00
										 |  |  |     return new_interpreter(tstate_p, config); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-01 11:33:44 +02:00
										 |  |  | PyThreadState * | 
					
						
							|  |  |  | Py_NewInterpreter(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-03-21 10:49:12 -06:00
										 |  |  |     PyThreadState *tstate = NULL; | 
					
						
							| 
									
										
										
										
											2023-05-02 21:40:00 -06:00
										 |  |  |     const PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT; | 
					
						
							|  |  |  |     PyStatus status = new_interpreter(&tstate, &config); | 
					
						
							| 
									
										
										
										
											2023-03-21 10:49:12 -06:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         Py_ExitStatusException(status); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return tstate; | 
					
						
							| 
									
										
										
										
											2020-05-01 11:33:44 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | /* Delete an interpreter and its last thread.  This requires that the
 | 
					
						
							|  |  |  |    given thread state is current, that the thread has no remaining | 
					
						
							|  |  |  |    frames, and that it is its interpreter's only remaining thread. | 
					
						
							|  |  |  |    It is a fatal error to violate these constraints. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-30 03:18:29 +00:00
										 |  |  |    (Py_FinalizeEx() doesn't have these constraints -- it zaps | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |    everything, regardless.) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Locking: as above. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | Py_EndInterpreter(PyThreadState *tstate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyInterpreterState *interp = tstate->interp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |     if (tstate != _PyThreadState_GET()) { | 
					
						
							| 
									
										
										
										
											2020-03-07 00:54:20 +01:00
										 |  |  |         Py_FatalError("thread is not current"); | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-08-17 11:16:03 +01:00
										 |  |  |     if (tstate->current_frame != NULL) { | 
					
						
							| 
									
										
										
										
											2020-03-07 00:54:20 +01:00
										 |  |  |         Py_FatalError("thread still has a frame"); | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-08 22:47:07 -07:00
										 |  |  |     interp->finalizing = 1; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 15:47:51 -06:00
										 |  |  |     // Wrap up existing "threading"-module-created, non-daemon threads.
 | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |     wait_for_thread_shutdown(tstate); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 15:02:19 -06:00
										 |  |  |     // Make any remaining pending calls.
 | 
					
						
							|  |  |  |     _Py_FinishPendingCalls(tstate); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 15:10:45 +01:00
										 |  |  |     _PyAtExit_Call(tstate->interp); | 
					
						
							| 
									
										
										
										
											2017-12-20 11:17:58 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-07 14:03:47 -07:00
										 |  |  |     if (tstate != interp->threads.head || tstate->next != NULL) { | 
					
						
							| 
									
										
										
										
											2020-03-07 00:54:20 +01:00
										 |  |  |         Py_FatalError("not the last thread"); | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 13:59:26 -06:00
										 |  |  |     /* Remaining daemon threads will automatically exit
 | 
					
						
							|  |  |  |        when they attempt to take the GIL (ex: PyEval_RestoreThread()). */ | 
					
						
							|  |  |  |     _PyInterpreterState_SetFinalizing(interp, tstate); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  |     // XXX Call something like _PyImport_Disable() here?
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _PyImport_FiniExternal(tstate->interp); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  |     finalize_modules(tstate); | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  |     _PyImport_FiniCore(tstate->interp); | 
					
						
							| 
									
										
										
										
											2020-10-30 18:03:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 18:39:12 +01:00
										 |  |  |     finalize_interp_clear(tstate); | 
					
						
							| 
									
										
										
										
											2021-02-19 15:10:45 +01:00
										 |  |  |     finalize_interp_delete(tstate->interp); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 13:59:26 -06:00
										 |  |  | int | 
					
						
							|  |  |  | _Py_IsInterpreterFinalizing(PyInterpreterState *interp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* We check the runtime first since, in a daemon thread,
 | 
					
						
							|  |  |  |        interp might be dangling pointer. */ | 
					
						
							|  |  |  |     PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(&_PyRuntime); | 
					
						
							|  |  |  |     if (finalizing == NULL) { | 
					
						
							|  |  |  |         finalizing = _PyInterpreterState_GetFinalizing(interp); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return finalizing != NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  | /* Add the __main__ module */ | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  | add_main_module(PyInterpreterState *interp) | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-08-23 22:59:00 +02:00
										 |  |  |     PyObject *m, *d, *ann_dict; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     m = PyImport_AddModule("__main__"); | 
					
						
							|  |  |  |     if (m == NULL) | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_ERR("can't create __main__ module"); | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     d = PyModule_GetDict(m); | 
					
						
							| 
									
										
										
										
											2016-09-08 20:50:03 -07:00
										 |  |  |     ann_dict = PyDict_New(); | 
					
						
							|  |  |  |     if ((ann_dict == NULL) || | 
					
						
							|  |  |  |         (PyDict_SetItemString(d, "__annotations__", ann_dict) < 0)) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_ERR("Failed to initialize __main__.__annotations__"); | 
					
						
							| 
									
										
										
										
											2016-09-08 20:50:03 -07:00
										 |  |  |     } | 
					
						
							|  |  |  |     Py_DECREF(ann_dict); | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-24 15:59:12 +02:00
										 |  |  |     int has_builtins = PyDict_ContainsString(d, "__builtins__"); | 
					
						
							|  |  |  |     if (has_builtins < 0) { | 
					
						
							|  |  |  |         return _PyStatus_ERR("Failed to test __main__.__builtins__"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!has_builtins) { | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         PyObject *bimod = PyImport_ImportModule("builtins"); | 
					
						
							|  |  |  |         if (bimod == NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |             return _PyStatus_ERR("Failed to retrieve builtins module"); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |             return _PyStatus_ERR("Failed to initialize __main__.__builtins__"); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         } | 
					
						
							|  |  |  |         Py_DECREF(bimod); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-28 16:17:58 -07:00
										 |  |  |     /* Main is a little special - BuiltinImporter is the most appropriate
 | 
					
						
							|  |  |  |      * initial setting for its __loader__ attribute. A more suitable value | 
					
						
							|  |  |  |      * will be set if __main__ gets further initialized later in the startup | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |      * process. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-08-23 22:59:00 +02:00
										 |  |  |     PyObject *loader; | 
					
						
							|  |  |  |     if (PyDict_GetItemStringRef(d, "__loader__", &loader) < 0) { | 
					
						
							|  |  |  |         return _PyStatus_ERR("Failed to test __main__.__loader__"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     int has_loader = !(loader == NULL || loader == Py_None); | 
					
						
							|  |  |  |     Py_XDECREF(loader); | 
					
						
							|  |  |  |     if (!has_loader) { | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  |         PyObject *loader = _PyImport_GetImportlibLoader(interp, | 
					
						
							|  |  |  |                                                         "BuiltinImporter"); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         if (loader == NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |             return _PyStatus_ERR("Failed to retrieve BuiltinImporter"); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (PyDict_SetItemString(d, "__loader__", loader) < 0) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |             return _PyStatus_ERR("Failed to initialize __main__.__loader__"); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         } | 
					
						
							|  |  |  |         Py_DECREF(loader); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Import the site module (not into __main__ though) */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  | init_import_site(void) | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | { | 
					
						
							|  |  |  |     PyObject *m; | 
					
						
							|  |  |  |     m = PyImport_ImportModule("site"); | 
					
						
							|  |  |  |     if (m == NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_ERR("Failed to import the site module"); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  |     Py_DECREF(m); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-04 17:29:57 +02:00
										 |  |  | /* Check if a file descriptor is valid or not.
 | 
					
						
							|  |  |  |    Return 0 if the file descriptor is invalid, return non-zero otherwise. */ | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | is_valid_fd(int fd) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 18:09:12 +02:00
										 |  |  | /* dup() is faster than fstat(): fstat() can require input/output operations,
 | 
					
						
							|  |  |  |    whereas dup() doesn't. There is a low risk of EMFILE/ENFILE at Python | 
					
						
							|  |  |  |    startup. Problem: dup() doesn't check if the file descriptor is valid on | 
					
						
							|  |  |  |    some platforms. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-28 20:40:27 +02:00
										 |  |  |    fcntl(fd, F_GETFD) is even faster, because it only checks the process table. | 
					
						
							| 
									
										
										
										
											2021-12-14 10:31:41 +09:00
										 |  |  |    It is preferred over dup() when available, since it cannot fail with the | 
					
						
							|  |  |  |    "too many open files" error (EMFILE). | 
					
						
							| 
									
										
										
										
											2021-11-28 20:40:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 18:09:12 +02:00
										 |  |  |    bpo-30225: On macOS Tiger, when stdout is redirected to a pipe and the other | 
					
						
							|  |  |  |    side of the pipe is closed, dup(1) succeed, whereas fstat(1, &st) fails with | 
					
						
							|  |  |  |    EBADF. FreeBSD has similar issue (bpo-32849). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-14 10:31:41 +09:00
										 |  |  |    Only use dup() on Linux where dup() is enough to detect invalid FD | 
					
						
							|  |  |  |    (bpo-32849). | 
					
						
							| 
									
										
										
										
											2021-11-28 20:40:27 +02:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2019-04-17 18:09:12 +02:00
										 |  |  |     if (fd < 0) { | 
					
						
							| 
									
										
										
										
											2015-09-04 17:29:57 +02:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 18:09:12 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-02 13:19:30 +02:00
										 |  |  | #if defined(F_GETFD) && ( \
 | 
					
						
							|  |  |  |         defined(__linux__) || \ | 
					
						
							|  |  |  |         defined(__APPLE__) || \ | 
					
						
							|  |  |  |         defined(__wasm__)) | 
					
						
							| 
									
										
										
										
											2021-12-13 21:57:59 +09:00
										 |  |  |     return fcntl(fd, F_GETFD) >= 0; | 
					
						
							|  |  |  | #elif defined(__linux__)
 | 
					
						
							|  |  |  |     int fd2 = dup(fd); | 
					
						
							| 
									
										
										
										
											2019-04-17 18:09:12 +02:00
										 |  |  |     if (fd2 >= 0) { | 
					
						
							| 
									
										
										
										
											2015-09-04 17:29:57 +02:00
										 |  |  |         close(fd2); | 
					
						
							| 
									
										
										
										
											2019-04-17 18:09:12 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     return (fd2 >= 0); | 
					
						
							| 
									
										
										
										
											2021-12-13 21:57:59 +09:00
										 |  |  | #elif defined(MS_WINDOWS)
 | 
					
						
							|  |  |  |     HANDLE hfile; | 
					
						
							|  |  |  |     _Py_BEGIN_SUPPRESS_IPH | 
					
						
							|  |  |  |     hfile = (HANDLE)_get_osfhandle(fd); | 
					
						
							|  |  |  |     _Py_END_SUPPRESS_IPH | 
					
						
							|  |  |  |     return (hfile != INVALID_HANDLE_VALUE | 
					
						
							|  |  |  |             && GetFileType(hfile) != FILE_TYPE_UNKNOWN); | 
					
						
							| 
									
										
										
										
											2019-04-17 18:09:12 +02:00
										 |  |  | #else
 | 
					
						
							|  |  |  |     struct stat st; | 
					
						
							|  |  |  |     return (fstat(fd, &st) == 0); | 
					
						
							| 
									
										
										
										
											2017-05-04 00:45:56 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-04 17:29:57 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* returns Py_None if the fd is not valid */ | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | static PyObject* | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | create_stdio(const PyConfig *config, PyObject* io, | 
					
						
							| 
									
										
										
										
											2015-12-25 20:01:53 +02:00
										 |  |  |     int fd, int write_mode, const char* name, | 
					
						
							| 
									
										
										
										
											2019-05-02 14:56:30 -04:00
										 |  |  |     const wchar_t* encoding, const wchar_t* errors) | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | { | 
					
						
							|  |  |  |     PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res; | 
					
						
							|  |  |  |     const char* mode; | 
					
						
							|  |  |  |     const char* newline; | 
					
						
							| 
									
										
										
										
											2017-10-04 20:25:40 +03:00
										 |  |  |     PyObject *line_buffering, *write_through; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     int buffering, isatty; | 
					
						
							| 
									
										
										
										
											2018-08-30 00:50:45 +02:00
										 |  |  |     const int buffered_stdio = config->buffered_stdio; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-04 17:29:57 +02:00
										 |  |  |     if (!is_valid_fd(fd)) | 
					
						
							|  |  |  |         Py_RETURN_NONE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     /* stdin is always opened in buffered mode, first because it shouldn't
 | 
					
						
							|  |  |  |        make a difference in common use cases, second because TextIOWrapper | 
					
						
							|  |  |  |        depends on the presence of a read1() method which only exists on | 
					
						
							|  |  |  |        buffered streams. | 
					
						
							|  |  |  |     */ | 
					
						
							| 
									
										
										
										
											2018-08-30 00:50:45 +02:00
										 |  |  |     if (!buffered_stdio && write_mode) | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         buffering = 0; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         buffering = -1; | 
					
						
							|  |  |  |     if (write_mode) | 
					
						
							|  |  |  |         mode = "wb"; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         mode = "rb"; | 
					
						
							| 
									
										
										
										
											2022-02-08 13:39:07 -07:00
										 |  |  |     buf = _PyObject_CallMethod(io, &_Py_ID(open), "isiOOOO", | 
					
						
							|  |  |  |                                fd, mode, buffering, | 
					
						
							|  |  |  |                                Py_None, Py_None, /* encoding, errors */ | 
					
						
							|  |  |  |                                Py_None, Py_False); /* newline, closefd */ | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     if (buf == NULL) | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (buffering) { | 
					
						
							| 
									
										
										
										
											2022-02-08 13:39:07 -07:00
										 |  |  |         raw = PyObject_GetAttr(buf, &_Py_ID(raw)); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         if (raw == NULL) | 
					
						
							|  |  |  |             goto error; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2022-11-10 09:03:39 +01:00
										 |  |  |         raw = Py_NewRef(buf); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-09 22:09:12 +01:00
										 |  |  | #ifdef HAVE_WINDOWS_CONSOLE_IO
 | 
					
						
							| 
									
										
										
										
											2016-08-30 21:22:36 -07:00
										 |  |  |     /* Windows console IO is always UTF-8 encoded */ | 
					
						
							| 
									
										
										
										
											2023-02-15 14:07:59 +01:00
										 |  |  |     PyTypeObject *winconsoleio_type = (PyTypeObject *)_PyImport_GetModuleAttr( | 
					
						
							|  |  |  |             &_Py_ID(_io), &_Py_ID(_WindowsConsoleIO)); | 
					
						
							|  |  |  |     if (winconsoleio_type == NULL) { | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     int is_subclass = PyObject_TypeCheck(raw, winconsoleio_type); | 
					
						
							|  |  |  |     Py_DECREF(winconsoleio_type); | 
					
						
							|  |  |  |     if (is_subclass) { | 
					
						
							| 
									
										
										
										
											2019-05-02 14:56:30 -04:00
										 |  |  |         encoding = L"utf-8"; | 
					
						
							| 
									
										
										
										
											2023-02-15 14:07:59 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-08-30 21:22:36 -07:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     text = PyUnicode_FromString(name); | 
					
						
							| 
									
										
										
										
											2022-02-08 13:39:07 -07:00
										 |  |  |     if (text == NULL || PyObject_SetAttr(raw, &_Py_ID(name), text) < 0) | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         goto error; | 
					
						
							| 
									
										
										
										
											2022-02-08 13:39:07 -07:00
										 |  |  |     res = PyObject_CallMethodNoArgs(raw, &_Py_ID(isatty)); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     if (res == NULL) | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     isatty = PyObject_IsTrue(res); | 
					
						
							|  |  |  |     Py_DECREF(res); | 
					
						
							|  |  |  |     if (isatty == -1) | 
					
						
							|  |  |  |         goto error; | 
					
						
							| 
									
										
										
										
											2018-08-30 00:50:45 +02:00
										 |  |  |     if (!buffered_stdio) | 
					
						
							| 
									
										
										
										
											2017-10-04 20:25:40 +03:00
										 |  |  |         write_through = Py_True; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         write_through = Py_False; | 
					
						
							| 
									
										
										
										
											2020-01-01 23:21:43 +01:00
										 |  |  |     if (buffered_stdio && (isatty || fd == fileno(stderr))) | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         line_buffering = Py_True; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         line_buffering = Py_False; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_CLEAR(raw); | 
					
						
							|  |  |  |     Py_CLEAR(text); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  |     /* sys.stdin: enable universal newline mode, translate "\r\n" and "\r"
 | 
					
						
							|  |  |  |        newlines to "\n". | 
					
						
							|  |  |  |        sys.stdout and sys.stderr: translate "\n" to "\r\n". */ | 
					
						
							|  |  |  |     newline = NULL; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     /* sys.stdin: split lines at "\n".
 | 
					
						
							|  |  |  |        sys.stdout and sys.stderr: don't translate newlines (use "\n"). */ | 
					
						
							|  |  |  |     newline = "\n"; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-02 14:56:30 -04:00
										 |  |  |     PyObject *encoding_str = PyUnicode_FromWideChar(encoding, -1); | 
					
						
							|  |  |  |     if (encoding_str == NULL) { | 
					
						
							|  |  |  |         Py_CLEAR(buf); | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyObject *errors_str = PyUnicode_FromWideChar(errors, -1); | 
					
						
							|  |  |  |     if (errors_str == NULL) { | 
					
						
							|  |  |  |         Py_CLEAR(buf); | 
					
						
							|  |  |  |         Py_CLEAR(encoding_str); | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 13:39:07 -07:00
										 |  |  |     stream = _PyObject_CallMethod(io, &_Py_ID(TextIOWrapper), "OOOsOO", | 
					
						
							|  |  |  |                                   buf, encoding_str, errors_str, | 
					
						
							|  |  |  |                                   newline, line_buffering, write_through); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     Py_CLEAR(buf); | 
					
						
							| 
									
										
										
										
											2019-05-02 14:56:30 -04:00
										 |  |  |     Py_CLEAR(encoding_str); | 
					
						
							|  |  |  |     Py_CLEAR(errors_str); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     if (stream == NULL) | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (write_mode) | 
					
						
							|  |  |  |         mode = "w"; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         mode = "r"; | 
					
						
							|  |  |  |     text = PyUnicode_FromString(mode); | 
					
						
							| 
									
										
										
										
											2022-02-08 13:39:07 -07:00
										 |  |  |     if (!text || PyObject_SetAttr(stream, &_Py_ID(mode), text) < 0) | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         goto error; | 
					
						
							|  |  |  |     Py_CLEAR(text); | 
					
						
							|  |  |  |     return stream; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | error: | 
					
						
							|  |  |  |     Py_XDECREF(buf); | 
					
						
							|  |  |  |     Py_XDECREF(stream); | 
					
						
							|  |  |  |     Py_XDECREF(text); | 
					
						
							|  |  |  |     Py_XDECREF(raw); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-04 17:29:57 +02:00
										 |  |  |     if (PyErr_ExceptionMatches(PyExc_OSError) && !is_valid_fd(fd)) { | 
					
						
							|  |  |  |         /* Issue #24891: the file descriptor was closed after the first
 | 
					
						
							|  |  |  |            is_valid_fd() check was called. Ignore the OSError and set the | 
					
						
							|  |  |  |            stream to None. */ | 
					
						
							|  |  |  |         PyErr_Clear(); | 
					
						
							|  |  |  |         Py_RETURN_NONE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-12 10:44:53 +02:00
										 |  |  | /* Set builtins.open to io.open */ | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2020-03-12 02:49:05 -05:00
										 |  |  | init_set_builtins_open(void) | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-06-14 07:15:26 +03:00
										 |  |  |     PyObject *wrapper; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     PyObject *bimod = NULL; | 
					
						
							| 
									
										
										
										
											2019-11-22 16:19:14 +01:00
										 |  |  |     PyStatus res = _PyStatus_OK(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!(bimod = PyImport_ImportModule("builtins"))) { | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-14 07:15:26 +03:00
										 |  |  |     if (!(wrapper = _PyImport_GetModuleAttrString("io", "open"))) { | 
					
						
							| 
									
										
										
										
											2019-11-22 16:19:14 +01:00
										 |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Set builtins.open */ | 
					
						
							|  |  |  |     if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) { | 
					
						
							|  |  |  |         Py_DECREF(wrapper); | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     Py_DECREF(wrapper); | 
					
						
							|  |  |  |     goto done; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | error: | 
					
						
							|  |  |  |     res = _PyStatus_ERR("can't initialize io.open"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | done: | 
					
						
							|  |  |  |     Py_XDECREF(bimod); | 
					
						
							|  |  |  |     return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-12 10:44:53 +02:00
										 |  |  | /* Create sys.stdin, sys.stdout and sys.stderr */ | 
					
						
							| 
									
										
										
										
											2019-11-22 16:19:14 +01:00
										 |  |  | static PyStatus | 
					
						
							|  |  |  | init_sys_streams(PyThreadState *tstate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *iomod = NULL; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     PyObject *std = NULL; | 
					
						
							| 
									
										
										
										
											2017-11-15 18:11:45 -08:00
										 |  |  |     int fd; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     PyObject * encoding_attr; | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyStatus res = _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2020-04-13 03:04:28 +02:00
										 |  |  |     const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp); | 
					
						
							| 
									
										
										
										
											2018-08-29 11:47:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-22 17:39:03 +01:00
										 |  |  |     /* Check that stdin is not a directory
 | 
					
						
							|  |  |  |        Using shell redirection, you can redirect stdin to a directory, | 
					
						
							|  |  |  |        crashing the Python interpreter. Catch this common mistake here | 
					
						
							|  |  |  |        and output a useful error message. Note that under MS Windows, | 
					
						
							|  |  |  |        the shell already prevents that. */ | 
					
						
							|  |  |  | #ifndef MS_WINDOWS
 | 
					
						
							|  |  |  |     struct _Py_stat_struct sb; | 
					
						
							|  |  |  |     if (_Py_fstat_noraise(fileno(stdin), &sb) == 0 && | 
					
						
							|  |  |  |         S_ISDIR(sb.st_mode)) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         return _PyStatus_ERR("<stdin> is a directory, cannot continue"); | 
					
						
							| 
									
										
										
										
											2019-01-22 17:39:03 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     if (!(iomod = PyImport_ImportModule("io"))) { | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Set sys.stdin */ | 
					
						
							|  |  |  |     fd = fileno(stdin); | 
					
						
							|  |  |  |     /* Under some conditions stdin, stdout and stderr may not be connected
 | 
					
						
							|  |  |  |      * and fileno() may point to an invalid file descriptor. For example | 
					
						
							|  |  |  |      * GUI apps don't have valid standard streams by default. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2018-08-30 00:50:45 +02:00
										 |  |  |     std = create_stdio(config, iomod, fd, 0, "<stdin>", | 
					
						
							| 
									
										
										
										
											2018-08-29 11:47:29 +02:00
										 |  |  |                        config->stdio_encoding, | 
					
						
							|  |  |  |                        config->stdio_errors); | 
					
						
							| 
									
										
										
										
											2015-09-04 17:29:57 +02:00
										 |  |  |     if (std == NULL) | 
					
						
							|  |  |  |         goto error; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     PySys_SetObject("__stdin__", std); | 
					
						
							| 
									
										
										
										
											2022-02-08 13:39:07 -07:00
										 |  |  |     _PySys_SetAttr(&_Py_ID(stdin), std); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     Py_DECREF(std); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Set sys.stdout */ | 
					
						
							|  |  |  |     fd = fileno(stdout); | 
					
						
							| 
									
										
										
										
											2018-08-30 00:50:45 +02:00
										 |  |  |     std = create_stdio(config, iomod, fd, 1, "<stdout>", | 
					
						
							| 
									
										
										
										
											2018-08-29 11:47:29 +02:00
										 |  |  |                        config->stdio_encoding, | 
					
						
							|  |  |  |                        config->stdio_errors); | 
					
						
							| 
									
										
										
										
											2015-09-04 17:29:57 +02:00
										 |  |  |     if (std == NULL) | 
					
						
							|  |  |  |         goto error; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     PySys_SetObject("__stdout__", std); | 
					
						
							| 
									
										
										
										
											2022-02-08 13:39:07 -07:00
										 |  |  |     _PySys_SetAttr(&_Py_ID(stdout), std); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     Py_DECREF(std); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 1 /* Disable this if you have trouble debugging bootstrap stuff */
 | 
					
						
							|  |  |  |     /* Set sys.stderr, replaces the preliminary stderr */ | 
					
						
							|  |  |  |     fd = fileno(stderr); | 
					
						
							| 
									
										
										
										
											2018-08-30 00:50:45 +02:00
										 |  |  |     std = create_stdio(config, iomod, fd, 1, "<stderr>", | 
					
						
							| 
									
										
										
										
											2018-08-29 11:47:29 +02:00
										 |  |  |                        config->stdio_encoding, | 
					
						
							| 
									
										
										
										
											2019-05-02 14:56:30 -04:00
										 |  |  |                        L"backslashreplace"); | 
					
						
							| 
									
										
										
										
											2015-09-04 17:29:57 +02:00
										 |  |  |     if (std == NULL) | 
					
						
							|  |  |  |         goto error; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Same as hack above, pre-import stderr's codec to avoid recursion
 | 
					
						
							|  |  |  |        when import.c tries to write to stderr in verbose mode. */ | 
					
						
							|  |  |  |     encoding_attr = PyObject_GetAttrString(std, "encoding"); | 
					
						
							|  |  |  |     if (encoding_attr != NULL) { | 
					
						
							| 
									
										
										
										
											2016-11-20 10:16:47 +02:00
										 |  |  |         const char *std_encoding = PyUnicode_AsUTF8(encoding_attr); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         if (std_encoding != NULL) { | 
					
						
							|  |  |  |             PyObject *codec_info = _PyCodec_Lookup(std_encoding); | 
					
						
							|  |  |  |             Py_XDECREF(codec_info); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         Py_DECREF(encoding_attr); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |     _PyErr_Clear(tstate);  /* Not a fatal error if codec isn't available */ | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (PySys_SetObject("__stderr__", std) < 0) { | 
					
						
							|  |  |  |         Py_DECREF(std); | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-02-08 13:39:07 -07:00
										 |  |  |     if (_PySys_SetAttr(&_Py_ID(stderr), std) < 0) { | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         Py_DECREF(std); | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     Py_DECREF(std); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-15 18:11:45 -08:00
										 |  |  |     goto done; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-15 18:11:45 -08:00
										 |  |  | error: | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     res = _PyStatus_ERR("can't initialize sys standard streams"); | 
					
						
							| 
									
										
										
										
											2017-11-15 18:11:45 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | done: | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     Py_XDECREF(iomod); | 
					
						
							| 
									
										
										
										
											2017-11-15 18:11:45 -08:00
										 |  |  |     return res; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 16:53:12 +01:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  | _Py_FatalError_DumpTracebacks(int fd, PyInterpreterState *interp, | 
					
						
							|  |  |  |                               PyThreadState *tstate) | 
					
						
							| 
									
										
										
										
											2016-03-14 16:53:12 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |     PUTS(fd, "\n"); | 
					
						
							| 
									
										
										
										
											2016-03-14 16:53:12 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* display the current Python stack */ | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  |     _Py_DumpTracebackThreads(fd, interp, tstate); | 
					
						
							| 
									
										
										
										
											2016-03-14 16:53:12 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-24 12:01:30 +01:00
										 |  |  | /* Print the current exception (if an exception is set) with its traceback,
 | 
					
						
							| 
									
										
										
										
											2016-03-14 16:53:12 +01:00
										 |  |  |    or display the current Python stack. | 
					
						
							| 
									
										
										
										
											2015-03-24 12:01:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 16:53:12 +01:00
										 |  |  |    Don't call PyErr_PrintEx() and the except hook, because Py_FatalError() is | 
					
						
							|  |  |  |    called on catastrophic cases. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Return 1 if the traceback was displayed, 0 otherwise. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							| 
									
										
										
										
											2020-03-12 02:49:05 -05:00
										 |  |  | _Py_FatalError_PrintExc(PyThreadState *tstate) | 
					
						
							| 
									
										
										
										
											2015-03-24 12:01:30 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-03-16 22:18:04 +00:00
										 |  |  |     PyObject *exc = _PyErr_GetRaisedException(tstate); | 
					
						
							|  |  |  |     if (exc == NULL) { | 
					
						
							| 
									
										
										
										
											2015-03-24 12:01:30 +01:00
										 |  |  |         /* No current exception */ | 
					
						
							| 
									
										
										
										
											2016-03-14 16:53:12 +01:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2015-03-24 12:01:30 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-16 22:18:04 +00:00
										 |  |  |     PyObject *ferr = _PySys_GetAttr(tstate, &_Py_ID(stderr)); | 
					
						
							| 
									
										
										
										
											2015-03-24 13:46:18 +01:00
										 |  |  |     if (ferr == NULL || ferr == Py_None) { | 
					
						
							|  |  |  |         /* sys.stderr is not set yet or set to None,
 | 
					
						
							|  |  |  |            no need to try to display the exception */ | 
					
						
							| 
									
										
										
										
											2023-03-19 15:18:24 +00:00
										 |  |  |         Py_DECREF(exc); | 
					
						
							| 
									
										
										
										
											2016-03-14 16:53:12 +01:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2015-03-24 13:46:18 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-16 22:18:04 +00:00
										 |  |  |     PyErr_DisplayException(exc); | 
					
						
							| 
									
										
										
										
											2015-03-24 12:01:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-16 22:18:04 +00:00
										 |  |  |     PyObject *tb = PyException_GetTraceback(exc); | 
					
						
							|  |  |  |     int has_tb = (tb != NULL) && (tb != Py_None); | 
					
						
							| 
									
										
										
										
											2015-03-24 12:01:30 +01:00
										 |  |  |     Py_XDECREF(tb); | 
					
						
							| 
									
										
										
										
											2023-03-19 15:18:24 +00:00
										 |  |  |     Py_DECREF(exc); | 
					
						
							| 
									
										
										
										
											2015-03-24 13:46:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* sys.stderr may be buffered: call sys.stderr.flush() */ | 
					
						
							| 
									
										
										
										
											2023-09-23 09:35:30 +03:00
										 |  |  |     if (_PyFile_Flush(ferr) < 0) { | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |         _PyErr_Clear(tstate); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-03-24 13:46:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 16:53:12 +01:00
										 |  |  |     return has_tb; | 
					
						
							| 
									
										
										
										
											2015-03-24 12:01:30 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-03-14 16:53:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | /* Print fatal error message and abort */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-04 09:50:12 -07:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | fatal_output_debug(const char *msg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* buffer of 256 bytes allocated on the stack */ | 
					
						
							|  |  |  |     WCHAR buffer[256 / sizeof(WCHAR)]; | 
					
						
							|  |  |  |     size_t buflen = Py_ARRAY_LENGTH(buffer) - 1; | 
					
						
							|  |  |  |     size_t msglen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     OutputDebugStringW(L"Fatal Python error: "); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     msglen = strlen(msg); | 
					
						
							|  |  |  |     while (msglen) { | 
					
						
							|  |  |  |         size_t i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (buflen > msglen) { | 
					
						
							|  |  |  |             buflen = msglen; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Convert the message to wchar_t. This uses a simple one-to-one
 | 
					
						
							|  |  |  |            conversion, assuming that the this error message actually uses | 
					
						
							|  |  |  |            ASCII only. If this ceases to be true, we will have to convert. */ | 
					
						
							|  |  |  |         for (i=0; i < buflen; ++i) { | 
					
						
							|  |  |  |             buffer[i] = msg[i]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         buffer[i] = L'\0'; | 
					
						
							|  |  |  |         OutputDebugStringW(buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         msg += buflen; | 
					
						
							|  |  |  |         msglen -= buflen; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     OutputDebugStringW(L"\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  | fatal_error_dump_runtime(int fd, _PyRuntimeState *runtime) | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |     PUTS(fd, "Python runtime state: "); | 
					
						
							| 
									
										
										
										
											2020-03-07 00:24:23 +01:00
										 |  |  |     PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime); | 
					
						
							|  |  |  |     if (finalizing) { | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |         PUTS(fd, "finalizing (tstate=0x"); | 
					
						
							|  |  |  |         _Py_DumpHexadecimal(fd, (uintptr_t)finalizing, sizeof(finalizing) * 2); | 
					
						
							|  |  |  |         PUTS(fd, ")"); | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else if (runtime->initialized) { | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |         PUTS(fd, "initialized"); | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else if (runtime->core_initialized) { | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |         PUTS(fd, "core initialized"); | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else if (runtime->preinitialized) { | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |         PUTS(fd, "preinitialized"); | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else if (runtime->preinitializing) { | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |         PUTS(fd, "preinitializing"); | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |         PUTS(fd, "unknown"); | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |     PUTS(fd, "\n"); | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  | static inline void _Py_NO_RETURN | 
					
						
							|  |  |  | fatal_error_exit(int status) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (status < 0) { | 
					
						
							|  |  |  | #if defined(MS_WINDOWS) && defined(_DEBUG)
 | 
					
						
							|  |  |  |         DebugBreak(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         abort(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         exit(status); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 23:35:27 +01:00
										 |  |  | // Dump the list of extension modules of sys.modules, excluding stdlib modules
 | 
					
						
							| 
									
										
										
										
											2021-01-25 23:12:50 +01:00
										 |  |  | // (sys.stdlib_module_names), into fd file descriptor.
 | 
					
						
							| 
									
										
										
										
											2021-01-19 23:35:27 +01:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2021-01-18 20:47:13 +01:00
										 |  |  | // This function is called by a signal handler in faulthandler: avoid memory
 | 
					
						
							| 
									
										
										
										
											2021-01-19 23:35:27 +01:00
										 |  |  | // allocations and keep the implementation simple. For example, the list is not
 | 
					
						
							|  |  |  | // sorted on purpose.
 | 
					
						
							| 
									
										
										
										
											2021-01-18 20:47:13 +01:00
										 |  |  | void | 
					
						
							|  |  |  | _Py_DumpExtensionModules(int fd, PyInterpreterState *interp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (interp == NULL) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-02-15 15:32:31 -07:00
										 |  |  |     PyObject *modules = _PyImport_GetModules(interp); | 
					
						
							| 
									
										
										
										
											2021-01-19 23:35:27 +01:00
										 |  |  |     if (modules == NULL || !PyDict_Check(modules)) { | 
					
						
							| 
									
										
										
										
											2021-01-18 20:47:13 +01:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  |     Py_ssize_t pos; | 
					
						
							|  |  |  |     PyObject *key, *value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Avoid PyDict_GetItemString() which calls PyUnicode_FromString(),
 | 
					
						
							|  |  |  |     // memory cannot be allocated on the heap in a signal handler.
 | 
					
						
							|  |  |  |     // Iterate on the dict instead.
 | 
					
						
							| 
									
										
										
										
											2021-01-25 23:12:50 +01:00
										 |  |  |     PyObject *stdlib_module_names = NULL; | 
					
						
							| 
									
										
										
										
											2021-04-07 23:12:45 +02:00
										 |  |  |     if (interp->sysdict != NULL) { | 
					
						
							|  |  |  |         pos = 0; | 
					
						
							|  |  |  |         while (PyDict_Next(interp->sysdict, &pos, &key, &value)) { | 
					
						
							|  |  |  |             if (PyUnicode_Check(key) | 
					
						
							|  |  |  |                && PyUnicode_CompareWithASCIIString(key, "stdlib_module_names") == 0) { | 
					
						
							|  |  |  |                 stdlib_module_names = value; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-01-25 23:12:50 +01:00
										 |  |  |     // If we failed to get sys.stdlib_module_names or it's not a frozenset,
 | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  |     // don't exclude stdlib modules.
 | 
					
						
							| 
									
										
										
										
											2021-01-25 23:12:50 +01:00
										 |  |  |     if (stdlib_module_names != NULL && !PyFrozenSet_Check(stdlib_module_names)) { | 
					
						
							|  |  |  |         stdlib_module_names = NULL; | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // List extensions
 | 
					
						
							| 
									
										
										
										
											2021-01-19 23:35:27 +01:00
										 |  |  |     int header = 1; | 
					
						
							|  |  |  |     Py_ssize_t count = 0; | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  |     pos = 0; | 
					
						
							| 
									
										
										
										
											2021-01-18 20:47:13 +01:00
										 |  |  |     while (PyDict_Next(modules, &pos, &key, &value)) { | 
					
						
							|  |  |  |         if (!PyUnicode_Check(key)) { | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!_PyModule_IsExtension(value)) { | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-01-19 23:35:27 +01:00
										 |  |  |         // Use the module name from the sys.modules key,
 | 
					
						
							|  |  |  |         // don't attempt to get the module object name.
 | 
					
						
							| 
									
										
										
										
											2021-01-25 23:12:50 +01:00
										 |  |  |         if (stdlib_module_names != NULL) { | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  |             int is_stdlib_ext = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-25 23:12:50 +01:00
										 |  |  |             Py_ssize_t i = 0; | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  |             PyObject *item; | 
					
						
							|  |  |  |             Py_hash_t hash; | 
					
						
							| 
									
										
										
										
											2021-01-25 23:12:50 +01:00
										 |  |  |             while (_PySet_NextEntry(stdlib_module_names, &i, &item, &hash)) { | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  |                 if (PyUnicode_Check(item) | 
					
						
							|  |  |  |                     && PyUnicode_Compare(key, item) == 0) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     is_stdlib_ext = 1; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (is_stdlib_ext) { | 
					
						
							|  |  |  |                 // Ignore stdlib extension
 | 
					
						
							|  |  |  |                 continue; | 
					
						
							| 
									
										
										
										
											2021-01-19 23:35:27 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (header) { | 
					
						
							|  |  |  |             PUTS(fd, "\nExtension modules: "); | 
					
						
							|  |  |  |             header = 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2021-01-18 20:47:13 +01:00
										 |  |  |             PUTS(fd, ", "); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         _Py_DumpASCII(fd, key); | 
					
						
							| 
									
										
										
										
											2021-01-19 23:35:27 +01:00
										 |  |  |         count++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (count) { | 
					
						
							|  |  |  |         PUTS(fd, " (total: "); | 
					
						
							|  |  |  |         _Py_DumpDecimal(fd, count); | 
					
						
							|  |  |  |         PUTS(fd, ")"); | 
					
						
							|  |  |  |         PUTS(fd, "\n"); | 
					
						
							| 
									
										
										
										
											2021-01-18 20:47:13 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-25 13:02:55 -08:00
										 |  |  | static void _Py_NO_RETURN | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  | fatal_error(int fd, int header, const char *prefix, const char *msg, | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  |             int status) | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-03-25 01:55:14 +01:00
										 |  |  |     static int reentrant = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (reentrant) { | 
					
						
							|  |  |  |         /* Py_FatalError() caused a second fatal error.
 | 
					
						
							|  |  |  |            Example: flush_std_files() raises a recursion error. */ | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  |         fatal_error_exit(status); | 
					
						
							| 
									
										
										
										
											2015-03-25 01:55:14 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     reentrant = 1; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  |     if (header) { | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |         PUTS(fd, "Fatal Python error: "); | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  |         if (prefix) { | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |             PUTS(fd, prefix); | 
					
						
							|  |  |  |             PUTS(fd, ": "); | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (msg) { | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |             PUTS(fd, msg); | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |             PUTS(fd, "<message not set>"); | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |         PUTS(fd, "\n"); | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-03-24 12:01:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  |     _PyRuntimeState *runtime = &_PyRuntime; | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |     fatal_error_dump_runtime(fd, runtime); | 
					
						
							| 
									
										
										
										
											2018-11-01 00:26:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  |     /* Check if the current thread has a Python thread state
 | 
					
						
							|  |  |  |        and holds the GIL. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        tss_tstate is NULL if Py_FatalError() is called from a C thread which | 
					
						
							|  |  |  |        has no Python thread state. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        tss_tstate != tstate if the current Python thread does not hold the GIL. | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2023-05-04 16:21:01 +02:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |     PyInterpreterState *interp = NULL; | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  |     PyThreadState *tss_tstate = PyGILState_GetThisThreadState(); | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |     if (tstate != NULL) { | 
					
						
							|  |  |  |         interp = tstate->interp; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (tss_tstate != NULL) { | 
					
						
							|  |  |  |         interp = tss_tstate->interp; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  |     int has_tstate_and_gil = (tss_tstate != NULL && tss_tstate == tstate); | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-01 00:26:41 +01:00
										 |  |  |     if (has_tstate_and_gil) { | 
					
						
							|  |  |  |         /* If an exception is set, print the exception with its traceback */ | 
					
						
							| 
									
										
										
										
											2020-03-12 02:49:05 -05:00
										 |  |  |         if (!_Py_FatalError_PrintExc(tss_tstate)) { | 
					
						
							| 
									
										
										
										
											2018-11-01 00:26:41 +01:00
										 |  |  |             /* No exception is set, or an exception is set without traceback */ | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  |             _Py_FatalError_DumpTracebacks(fd, interp, tss_tstate); | 
					
						
							| 
									
										
										
										
											2018-11-01 00:26:41 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-09-18 01:35:33 +02:00
										 |  |  |         _Py_FatalError_DumpTracebacks(fd, interp, tss_tstate); | 
					
						
							| 
									
										
										
										
											2017-10-04 09:50:12 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-03-24 12:01:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-18 20:47:13 +01:00
										 |  |  |     _Py_DumpExtensionModules(fd, interp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-04 09:50:12 -07:00
										 |  |  |     /* The main purpose of faulthandler is to display the traceback.
 | 
					
						
							|  |  |  |        This function already did its best to display a traceback. | 
					
						
							|  |  |  |        Disable faulthandler to prevent writing a second traceback | 
					
						
							|  |  |  |        on abort(). */ | 
					
						
							| 
									
										
										
										
											2016-03-16 23:19:15 +01:00
										 |  |  |     _PyFaulthandler_Fini(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 16:53:12 +01:00
										 |  |  |     /* Check if the current Python thread hold the GIL */ | 
					
						
							| 
									
										
										
										
											2018-11-01 00:26:41 +01:00
										 |  |  |     if (has_tstate_and_gil) { | 
					
						
							| 
									
										
										
										
											2016-03-14 16:53:12 +01:00
										 |  |  |         /* Flush sys.stdout and sys.stderr */ | 
					
						
							|  |  |  |         flush_std_files(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-03-24 13:46:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							| 
									
										
										
										
											2017-10-04 09:50:12 -07:00
										 |  |  |     fatal_output_debug(msg); | 
					
						
							| 
									
										
										
										
											2015-03-25 01:55:14 +01:00
										 |  |  | #endif /* MS_WINDOWS */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  |     fatal_error_exit(status); | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-07 00:54:20 +01:00
										 |  |  | #undef Py_FatalError
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 01:41:59 +01:00
										 |  |  | void _Py_NO_RETURN | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  | Py_FatalError(const char *msg) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |     fatal_error(fileno(stderr), 1, NULL, msg, -1); | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-07 00:54:20 +01:00
										 |  |  | void _Py_NO_RETURN | 
					
						
							|  |  |  | _Py_FatalErrorFunc(const char *func, const char *msg) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |     fatal_error(fileno(stderr), 1, func, msg, -1); | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void _Py_NO_RETURN | 
					
						
							|  |  |  | _Py_FatalErrorFormat(const char *func, const char *format, ...) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     static int reentrant = 0; | 
					
						
							|  |  |  |     if (reentrant) { | 
					
						
							|  |  |  |         /* _Py_FatalErrorFormat() caused a second fatal error */ | 
					
						
							|  |  |  |         fatal_error_exit(-1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     reentrant = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     FILE *stream = stderr; | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |     const int fd = fileno(stream); | 
					
						
							|  |  |  |     PUTS(fd, "Fatal Python error: "); | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  |     if (func) { | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |         PUTS(fd, func); | 
					
						
							|  |  |  |         PUTS(fd, ": "); | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     va_list vargs; | 
					
						
							|  |  |  |     va_start(vargs, format); | 
					
						
							|  |  |  |     vfprintf(stream, format, vargs); | 
					
						
							|  |  |  |     va_end(vargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fputs("\n", stream); | 
					
						
							|  |  |  |     fflush(stream); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |     fatal_error(fd, 0, NULL, NULL, -1); | 
					
						
							| 
									
										
										
										
											2020-03-07 00:54:20 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 23:04:34 +02:00
										 |  |  | void _Py_NO_RETURN | 
					
						
							|  |  |  | _Py_FatalRefcountErrorFunc(const char *func, const char *msg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _Py_FatalErrorFormat(func, | 
					
						
							|  |  |  |                          "%s: bug likely caused by a refcount error " | 
					
						
							|  |  |  |                          "in a C extension", | 
					
						
							|  |  |  |                          msg); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 01:41:59 +01:00
										 |  |  | void _Py_NO_RETURN | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | Py_ExitStatusException(PyStatus status) | 
					
						
							| 
									
										
										
										
											2017-11-15 15:48:08 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_IS_EXIT(status)) { | 
					
						
							|  |  |  |         exit(status.exitcode); | 
					
						
							| 
									
										
										
										
											2019-03-01 12:14:41 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     else if (_PyStatus_IS_ERROR(status)) { | 
					
						
							| 
									
										
										
										
											2021-01-18 18:34:56 +01:00
										 |  |  |         fatal_error(fileno(stderr), 1, status.func, status.err_msg, 1); | 
					
						
							| 
									
										
										
										
											2019-03-01 12:14:41 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-16 16:39:26 +02:00
										 |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         Py_FatalError("Py_ExitStatusException() must not be called on success"); | 
					
						
							| 
									
										
										
										
											2019-05-16 16:39:26 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-14 23:07:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | /* Wait until threading._shutdown completes, provided
 | 
					
						
							|  |  |  |    the threading module was imported in the first place. | 
					
						
							|  |  |  |    The shutdown routine will wait until all non-daemon | 
					
						
							|  |  |  |    "threading" threads have completed. */ | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  | wait_for_thread_shutdown(PyThreadState *tstate) | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | { | 
					
						
							|  |  |  |     PyObject *result; | 
					
						
							| 
									
										
										
										
											2022-02-08 13:39:07 -07:00
										 |  |  |     PyObject *threading = PyImport_GetModule(&_Py_ID(threading)); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     if (threading == NULL) { | 
					
						
							| 
									
										
										
										
											2019-06-20 00:05:23 +02:00
										 |  |  |         if (_PyErr_Occurred(tstate)) { | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |             PyErr_FormatUnraisable("Exception ignored on threading shutdown"); | 
					
						
							| 
									
										
										
										
											2019-03-25 21:50:58 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         /* else: threading not imported */ | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-02-08 13:39:07 -07:00
										 |  |  |     result = PyObject_CallMethodNoArgs(threading, &_Py_ID(_shutdown)); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     if (result == NULL) { | 
					
						
							| 
									
										
										
										
											2023-11-02 11:16:34 +02:00
										 |  |  |         PyErr_FormatUnraisable("Exception ignored on threading shutdown"); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         Py_DECREF(result); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     Py_DECREF(threading); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int Py_AtExit(void (*func)(void)) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-06-08 12:08:28 -06:00
										 |  |  |     struct _atexit_runtime_state *state = &_PyRuntime.atexit; | 
					
						
							| 
									
										
										
										
											2023-12-07 14:33:40 -05:00
										 |  |  |     PyMutex_Lock(&state->mutex); | 
					
						
							| 
									
										
										
										
											2023-06-08 12:08:28 -06:00
										 |  |  |     if (state->ncallbacks >= NEXITFUNCS) { | 
					
						
							| 
									
										
										
										
											2023-12-07 14:33:40 -05:00
										 |  |  |         PyMutex_Unlock(&state->mutex); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2023-06-08 12:08:28 -06:00
										 |  |  |     } | 
					
						
							|  |  |  |     state->callbacks[state->ncallbacks++] = func; | 
					
						
							| 
									
										
										
										
											2023-12-07 14:33:40 -05:00
										 |  |  |     PyMutex_Unlock(&state->mutex); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2019-04-24 17:24:01 +02:00
										 |  |  | call_ll_exitfuncs(_PyRuntimeState *runtime) | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-06-08 12:08:28 -06:00
										 |  |  |     atexit_callbackfunc exitfunc; | 
					
						
							| 
									
										
										
										
											2023-04-05 18:42:02 -06:00
										 |  |  |     struct _atexit_runtime_state *state = &runtime->atexit; | 
					
						
							| 
									
										
										
										
											2023-06-08 12:08:28 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-07 14:33:40 -05:00
										 |  |  |     PyMutex_Lock(&state->mutex); | 
					
						
							| 
									
										
										
										
											2023-04-05 18:42:02 -06:00
										 |  |  |     while (state->ncallbacks > 0) { | 
					
						
							| 
									
										
										
										
											2019-04-26 05:49:26 +02:00
										 |  |  |         /* pop last function from the list */ | 
					
						
							| 
									
										
										
										
											2023-04-05 18:42:02 -06:00
										 |  |  |         state->ncallbacks--; | 
					
						
							| 
									
										
										
										
											2023-06-08 12:08:28 -06:00
										 |  |  |         exitfunc = state->callbacks[state->ncallbacks]; | 
					
						
							| 
									
										
										
										
											2023-04-05 18:42:02 -06:00
										 |  |  |         state->callbacks[state->ncallbacks] = NULL; | 
					
						
							| 
									
										
										
										
											2019-04-26 05:49:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-07 14:33:40 -05:00
										 |  |  |         PyMutex_Unlock(&state->mutex); | 
					
						
							| 
									
										
										
										
											2019-04-26 05:49:26 +02:00
										 |  |  |         exitfunc(); | 
					
						
							| 
									
										
										
										
											2023-12-07 14:33:40 -05:00
										 |  |  |         PyMutex_Lock(&state->mutex); | 
					
						
							| 
									
										
										
										
											2019-04-24 17:24:01 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-12-07 14:33:40 -05:00
										 |  |  |     PyMutex_Unlock(&state->mutex); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     fflush(stdout); | 
					
						
							|  |  |  |     fflush(stderr); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-01 16:41:25 +02:00
										 |  |  | void _Py_NO_RETURN | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | Py_Exit(int sts) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-11-30 03:18:29 +00:00
										 |  |  |     if (Py_FinalizeEx() < 0) { | 
					
						
							|  |  |  |         sts = 120; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     exit(sts); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * The file descriptor fd is considered ``interactive'' if either | 
					
						
							|  |  |  |  *   a) isatty(fd) is TRUE, or | 
					
						
							|  |  |  |  *   b) the -i flag was given, and the filename associated with | 
					
						
							|  |  |  |  *      the descriptor is NULL or "<stdin>" or "???". | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | Py_FdIsInteractive(FILE *fp, const char *filename) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-06-17 15:19:28 +02:00
										 |  |  |     if (isatty(fileno(fp))) { | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         return 1; | 
					
						
							| 
									
										
										
										
											2022-06-17 15:19:28 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (!_Py_GetConfig()->interactive) { | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2022-06-17 15:19:28 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     return ((filename == NULL) | 
					
						
							|  |  |  |             || (strcmp(filename, "<stdin>") == 0) | 
					
						
							|  |  |  |             || (strcmp(filename, "???") == 0)); | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-09 22:37:27 +01:00
										 |  |  | int | 
					
						
							|  |  |  | _Py_FdIsInteractive(FILE *fp, PyObject *filename) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-06-17 15:19:28 +02:00
										 |  |  |     if (isatty(fileno(fp))) { | 
					
						
							| 
									
										
										
										
											2020-12-09 22:37:27 +01:00
										 |  |  |         return 1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-06-17 15:19:28 +02:00
										 |  |  |     if (!_Py_GetConfig()->interactive) { | 
					
						
							| 
									
										
										
										
											2020-12-09 22:37:27 +01:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-06-17 15:19:28 +02:00
										 |  |  |     return ((filename == NULL) | 
					
						
							|  |  |  |             || (PyUnicode_CompareWithASCIIString(filename, "<stdin>") == 0) | 
					
						
							|  |  |  |             || (PyUnicode_CompareWithASCIIString(filename, "???") == 0)); | 
					
						
							| 
									
										
										
										
											2020-12-09 22:37:27 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  | /* Wrappers around sigaction() or signal(). */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyOS_sighandler_t | 
					
						
							|  |  |  | PyOS_getsig(int sig) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef HAVE_SIGACTION
 | 
					
						
							|  |  |  |     struct sigaction context; | 
					
						
							|  |  |  |     if (sigaction(sig, NULL, &context) == -1) | 
					
						
							|  |  |  |         return SIG_ERR; | 
					
						
							|  |  |  |     return context.sa_handler; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     PyOS_sighandler_t handler; | 
					
						
							|  |  |  | /* Special signal handling for the secure CRT in Visual Studio 2005 */ | 
					
						
							|  |  |  | #if defined(_MSC_VER) && _MSC_VER >= 1400
 | 
					
						
							|  |  |  |     switch (sig) { | 
					
						
							|  |  |  |     /* Only these signals are valid */ | 
					
						
							|  |  |  |     case SIGINT: | 
					
						
							|  |  |  |     case SIGILL: | 
					
						
							|  |  |  |     case SIGFPE: | 
					
						
							|  |  |  |     case SIGSEGV: | 
					
						
							|  |  |  |     case SIGTERM: | 
					
						
							|  |  |  |     case SIGBREAK: | 
					
						
							|  |  |  |     case SIGABRT: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     /* Don't call signal() with other values or it will assert */ | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         return SIG_ERR; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif /* _MSC_VER && _MSC_VER >= 1400 */
 | 
					
						
							|  |  |  |     handler = signal(sig, SIG_IGN); | 
					
						
							|  |  |  |     if (handler != SIG_ERR) | 
					
						
							|  |  |  |         signal(sig, handler); | 
					
						
							|  |  |  |     return handler; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * All of the code in this function must only use async-signal-safe functions, | 
					
						
							|  |  |  |  * listed at `man 7 signal` or | 
					
						
							|  |  |  |  * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | PyOS_sighandler_t | 
					
						
							|  |  |  | PyOS_setsig(int sig, PyOS_sighandler_t handler) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef HAVE_SIGACTION
 | 
					
						
							|  |  |  |     /* Some code in Modules/signalmodule.c depends on sigaction() being
 | 
					
						
							|  |  |  |      * used here if HAVE_SIGACTION is defined.  Fix that if this code | 
					
						
							|  |  |  |      * changes to invalidate that assumption. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     struct sigaction context, ocontext; | 
					
						
							|  |  |  |     context.sa_handler = handler; | 
					
						
							|  |  |  |     sigemptyset(&context.sa_mask); | 
					
						
							| 
									
										
										
										
											2021-03-04 21:49:30 -08:00
										 |  |  |     /* Using SA_ONSTACK is friendlier to other C/C++/Golang-VM code that
 | 
					
						
							|  |  |  |      * extension module or embedding code may use where tiny thread stacks | 
					
						
							|  |  |  |      * are used.  https://bugs.python.org/issue43390 */
 | 
					
						
							|  |  |  |     context.sa_flags = SA_ONSTACK; | 
					
						
							| 
									
										
										
										
											2014-11-20 21:39:37 +10:00
										 |  |  |     if (sigaction(sig, &context, &ocontext) == -1) | 
					
						
							|  |  |  |         return SIG_ERR; | 
					
						
							|  |  |  |     return ocontext.sa_handler; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     PyOS_sighandler_t oldhandler; | 
					
						
							|  |  |  |     oldhandler = signal(sig, handler); | 
					
						
							|  |  |  | #ifdef HAVE_SIGINTERRUPT
 | 
					
						
							|  |  |  |     siginterrupt(sig, 1); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     return oldhandler; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } |