/* Python interpreter top-level routines, including init/exit */

#include "Python.h"
#include "pycore_audit.h"         // _PySys_ClearAuditHooks()
#include "pycore_call.h"          // _PyObject_CallMethod()
#include "pycore_ceval.h"         // _PyEval_FiniGIL()
#include "pycore_codecs.h"        // _PyCodec_Lookup()
#include "pycore_context.h"       // _PyContext_Init()
#include "pycore_dict.h"          // _PyDict_Fini()
#include "pycore_exceptions.h"    // _PyExc_InitTypes()
#include "pycore_fileutils.h"     // _Py_ResetForceASCII()
#include "pycore_floatobject.h"   // _PyFloat_InitTypes()
#include "pycore_freelist.h"      // _PyObject_ClearFreeLists()
#include "pycore_global_objects_fini_generated.h"  // _PyStaticObjects_CheckRefcnt()
#include "pycore_initconfig.h"    // _PyStatus_OK()
#include "pycore_interpolation.h" // _PyInterpolation_InitTypes()
#include "pycore_long.h"          // _PyLong_InitTypes()
#include "pycore_moduleobject.h"  // _PyModule_InitModuleDictWatcher()
#include "pycore_object.h"        // _PyDebug_PrintTotalRefs()
#include "pycore_obmalloc.h"      // _PyMem_init_obmalloc()
#include "pycore_optimizer.h"     // _Py_Executors_InvalidateAll
#include "pycore_parking_lot.h"   // _PyParkingLot
#include "pycore_pathconfig.h"    // _PyPathConfig_UpdateGlobal()
#include "pycore_pyerrors.h"      // _PyErr_Occurred()
#include "pycore_pylifecycle.h"   // _PyErr_Print()
#include "pycore_pymem.h"         // _PyObject_DebugMallocStats()
#include "pycore_pystate.h"       // _PyThreadState_GET()
#include "pycore_runtime.h"       // _Py_ID()
#include "pycore_runtime_init.h"  // _PyRuntimeState_INIT
#include "pycore_setobject.h"     // _PySet_NextEntry()
#include "pycore_stats.h"         // _PyStats_InterpInit()
#include "pycore_sysmodule.h"     // _PySys_ClearAttrString()
#include "pycore_traceback.h"     // PyUnstable_TracebackThreads()
#include "pycore_tuple.h"         // _PyTuple_FromPair
#include "pycore_typeobject.h"    // _PyTypes_InitTypes()
#include "pycore_typevarobject.h" // _Py_clear_generic_types()
#include "pycore_unicodeobject.h" // _PyUnicode_InitTypes()
#include "pycore_uniqueid.h"      // _PyObject_FinalizeUniqueIdPool()
#include "pycore_warnings.h"      // _PyWarnings_InitState()
#include "pycore_weakref.h"       // _PyWeakref_GET_REF()

#if defined(PYMALLOC_USE_HUGEPAGES) && defined(MS_WINDOWS)
#include <Windows.h>
#endif

#include "opcode.h"

#include <locale.h>               // setlocale()
#include <stdlib.h>               // getenv()
#ifdef HAVE_UNISTD_H
#  include <unistd.h>             // isatty()
#endif

#if defined(__APPLE__)
#  include <AvailabilityMacros.h>
#  include <TargetConditionals.h>
#  include <mach-o/loader.h>
// The os_log unified logging APIs were introduced in macOS 10.12, iOS 10.0,
// tvOS 10.0, and watchOS 3.0;
#  if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
#    define HAS_APPLE_SYSTEM_LOG 1
#  elif defined(TARGET_OS_OSX) && TARGET_OS_OSX
#    if defined(MAC_OS_X_VERSION_10_12) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
#      define HAS_APPLE_SYSTEM_LOG 1
#    else
#      define HAS_APPLE_SYSTEM_LOG 0
#    endif
#  else
#    define HAS_APPLE_SYSTEM_LOG 0
#  endif

#  if HAS_APPLE_SYSTEM_LOG
#    include <os/log.h>
#  endif
#endif

#ifdef HAVE_SIGNAL_H
#  include <signal.h>             // SIG_IGN
#endif

#ifdef HAVE_LANGINFO_H
#  include <langinfo.h>           // nl_langinfo(CODESET)
#endif

#ifdef HAVE_FCNTL_H
#  include <fcntl.h>              // F_GETFD
#endif

#ifdef MS_WINDOWS
#  undef BYTE
#endif

#define PUTS(fd, str) (void)_Py_write_noraise(fd, str, (int)strlen(str))


/* Forward declarations */
static PyStatus add_main_module(PyInterpreterState *interp);
static PyStatus init_import_site(void);
static PyStatus init_set_builtins_open(void);
static PyStatus init_sys_streams(PyThreadState *tstate);
#ifdef __ANDROID__
static PyStatus init_android_streams(PyThreadState *tstate);
#endif
#if defined(__APPLE__) && HAS_APPLE_SYSTEM_LOG
static PyStatus init_apple_streams(PyThreadState *tstate);
#endif
static void wait_for_thread_shutdown(PyThreadState *tstate);
static void finalize_subinterpreters(void);
static void call_ll_exitfuncs(_PyRuntimeState *runtime);


/* 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 */

/* Suppress deprecation warning for PyBytesObject.ob_shash */
_Py_COMP_DIAG_PUSH
_Py_COMP_DIAG_IGNORE_DEPR_DECLS

GENERATE_DEBUG_SECTION(PyRuntime, _PyRuntimeState _PyRuntime)
= _PyRuntimeState_INIT(_PyRuntime, _Py_Debug_Cookie);
_Py_COMP_DIAG_POP


static int runtime_initialized = 0;

PyStatus
_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. */
    if (runtime_initialized) {
        return _PyStatus_OK();
    }
    runtime_initialized = 1;

    return _PyRuntimeState_Init(&_PyRuntime);
}

void
_PyRuntime_Finalize(void)
{
    _PyRuntimeState_Fini(&_PyRuntime);
    runtime_initialized = 0;
}

int
Py_IsFinalizing(void)
{
    return _PyRuntimeState_GetFinalizing(&_PyRuntime) != NULL;
}

/* Hack to force loading of object files */
int (*_PyOS_mystrnicmp_hack)(const char *, const char *, Py_ssize_t) = \
    PyOS_mystrnicmp; /* Python/pystrcmp.o */


/* APIs to access the initialization flags
 *
 * Can be called prior to Py_Initialize.
 */

int
_Py_IsCoreInitialized(void)
{
    return _PyRuntimeState_GetCoreInitialized(&_PyRuntime);
}

int
Py_IsInitialized(void)
{
    return _PyRuntimeState_GetInitialized(&_PyRuntime);
}


/* 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
_Py_LegacyLocaleDetected(int warn)
{
#ifndef MS_WINDOWS
    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;
        }
    }

    /* On non-Windows systems, the C locale is considered a legacy locale */
    /* 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.
     */
    const char *ctype_loc = setlocale(LC_CTYPE, NULL);
    if (ctype_loc == NULL) {
        return 0;
    }
    return (strcmp(ctype_loc, "C") == 0 || strcmp(ctype_loc, "POSIX") == 0);
#else
    /* Windows uses code pages instead of locales, so no locale is legacy */
    return 0;
#endif
}

#ifndef MS_WINDOWS
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
emit_stderr_warning_for_legacy_locale(_PyRuntimeState *runtime)
{
    const PyPreConfig *preconfig = &runtime->preconfig;
    if (preconfig->coerce_c_locale_warn && _Py_LegacyLocaleDetected(1)) {
        PySys_FormatStderr("%s", _C_LOCALE_WARNING);
    }
}
#endif   /* !defined(MS_WINDOWS) */

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"},
    {"UTF-8"},
    {NULL}
};


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;
        }
    }
    return 0;
}


#ifdef PY_COERCE_C_LOCALE
static const char C_LOCALE_COERCION_WARNING[] =
    "Python detected LC_CTYPE=C: LC_CTYPE coerced to %.20s (set another locale "
    "or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior).\n";

static int
_coerce_default_locale_settings(int warn, const _LocaleCoercionTarget *target)
{
    const char *newloc = target->locale_name;

    /* Reset locale back to currently configured defaults */
    _Py_SetLocaleFromEnv(LC_ALL);

    /* Set the relevant locale environment variable */
    if (setenv("LC_CTYPE", newloc, 1)) {
        fprintf(stderr,
                "Error setting LC_CTYPE, skipping C locale coercion\n");
        return 0;
    }
    if (warn) {
        fprintf(stderr, C_LOCALE_COERCION_WARNING, newloc);
    }

    /* Reconfigure with the overridden environment variables */
    _Py_SetLocaleFromEnv(LC_ALL);
    return 1;
}
#endif

int
_Py_CoerceLegacyLocale(int warn)
{
    int coerced = 0;
#ifdef PY_COERCE_C_LOCALE
    char *oldloc = NULL;

    oldloc = _PyMem_RawStrdup(setlocale(LC_CTYPE, NULL));
    if (oldloc == NULL) {
        return coerced;
    }

    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) {
#if !defined(_Py_FORCE_UTF8_LOCALE) && defined(HAVE_LANGINFO_H) && defined(CODESET)
                /* 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;
                }
#endif
                /* Successfully configured locale, so make it the default */
                coerced = _coerce_default_locale_settings(warn, target);
                goto done;
            }
        }
    }
    /* No C locale warning here, as Py_Initialize will emit one later */

    setlocale(LC_CTYPE, oldloc);

done:
    PyMem_RawFree(oldloc);
#endif
    return coerced;
}

/* _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)
{
    char *res;
#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
    res = setlocale(category, utf8_locale);
#else /* !defined(__ANDROID__) */
    res = setlocale(category, "");
#endif
    _Py_ResetForceASCII();
    return res;
}


static int
interpreter_update_config(PyThreadState *tstate, int only_update_path_config)
{
    const PyConfig *config = &tstate->interp->config;

    if (!only_update_path_config) {
        PyStatus status = _PyConfig_Write(config, tstate->interp->runtime);
        if (_PyStatus_EXCEPTION(status)) {
            _PyErr_SetFromPyStatus(status);
            return -1;
        }
    }

    if (_Py_IsMainInterpreter(tstate->interp)) {
        PyStatus status = _PyPathConfig_UpdateGlobal(config);
        if (_PyStatus_EXCEPTION(status)) {
            _PyErr_SetFromPyStatus(status);
            return -1;
        }
    }

    tstate->interp->long_state.max_str_digits = config->int_max_str_digits;

    // Update the sys module for the new configuration
    if (_PySys_UpdateConfig(tstate) < 0) {
        return -1;
    }
    return 0;
}


/* Global initializations.  Can be undone by Py_Finalize().  Don't
   call this twice without an intervening Py_Finalize() call.

   Every call to Py_InitializeFromConfig, Py_Initialize or Py_InitializeEx
   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.)

*/

static PyStatus
pyinit_core_reconfigure(_PyRuntimeState *runtime,
                        PyThreadState **tstate_p,
                        const PyConfig *config)
{
    PyStatus status;
    PyThreadState *tstate = _PyThreadState_GET();
    if (!tstate) {
        return _PyStatus_ERR("failed to read thread state");
    }
    *tstate_p = tstate;

    PyInterpreterState *interp = tstate->interp;
    if (interp == NULL) {
        return _PyStatus_ERR("can't make main interpreter");
    }
    assert(interp->_ready);

    status = _PyConfig_Write(config, runtime);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    status = _PyConfig_Copy(&interp->config, config);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }
    config = _PyInterpreterState_GetConfig(interp);

    if (config->_install_importlib) {
        status = _PyPathConfig_UpdateGlobal(config);
        if (_PyStatus_EXCEPTION(status)) {
            return status;
        }
    }
    return _PyStatus_OK();
}

#if defined(PYMALLOC_USE_HUGEPAGES) && defined(MS_WINDOWS)
static PyStatus
get_huge_pages_privilege(void)
{
    HANDLE hToken;
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        return _PyStatus_ERR("failed to open process token");
    }
    TOKEN_PRIVILEGES tp;
    if (!LookupPrivilegeValue(NULL, SE_LOCK_MEMORY_NAME, &tp.Privileges[0].Luid))
    {
        CloseHandle(hToken);
        return _PyStatus_ERR("failed to lookup SeLockMemoryPrivilege for huge pages");
    }
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    // AdjustTokenPrivileges can return with nonzero status (i.e. success)
    // but without having all privileges adjusted (ERROR_NOT_ALL_ASSIGNED).
    BOOL status = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
    DWORD error = GetLastError();
    if (!status || (error != ERROR_SUCCESS))
    {
        CloseHandle(hToken);
        return _PyStatus_ERR(
            "SeLockMemoryPrivilege not held; "
            "grant it via Local Security Policy or disable PYTHON_PYMALLOC_HUGEPAGES");
    }
    if (!CloseHandle(hToken))
    {
        return _PyStatus_ERR("failed to close process token handle");
    }
    return _PyStatus_OK();
}
#endif

static PyStatus
pycore_init_runtime(_PyRuntimeState *runtime,
                    const PyConfig *config)
{
    if (_PyRuntimeState_GetInitialized(runtime)) {
        return _PyStatus_ERR("main interpreter already initialized");
    }

    PyStatus status = _PyConfig_Write(config, runtime);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

#if defined(PYMALLOC_USE_HUGEPAGES) && defined(MS_WINDOWS)
    if (runtime->allocators.use_hugepages) {
        status = get_huge_pages_privilege();
        if (_PyStatus_EXCEPTION(status)) {
            return status;
        }
    }
#endif

    /* 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 :(
     */
    _PyRuntimeState_SetFinalizing(runtime, NULL);

    _Py_InitVersion();
    _Py_DumpTraceback_Init();

    status = _Py_HashRandomization_Init(config);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    status = _PyImport_Init();
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    status = _PyInterpreterState_Enable(runtime);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }
    return _PyStatus_OK();
}


static PyStatus
init_interp_settings(PyInterpreterState *interp,
                     const PyInterpreterConfig *config)
{
    assert(interp->feature_flags == 0);

    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");
    }
#ifdef Py_GIL_DISABLED
    if (!_Py_IsMainInterpreter(interp) &&
        !config->check_multi_interp_extensions)
    {
        return _PyStatus_ERR("The free-threaded build does not support "
                             "single-phase init extension modules in "
                             "subinterpreters");
    }
#endif

    if (config->allow_fork) {
        interp->feature_flags |= Py_RTFLAGS_FORK;
    }
    if (config->allow_exec) {
        interp->feature_flags |= Py_RTFLAGS_EXEC;
    }
    // Note that fork+exec is always allowed.

    if (config->allow_threads) {
        interp->feature_flags |= Py_RTFLAGS_THREADS;
    }
    if (config->allow_daemon_threads) {
        interp->feature_flags |= Py_RTFLAGS_DAEMON_THREADS;
    }

    if (config->check_multi_interp_extensions) {
        interp->feature_flags |= Py_RTFLAGS_MULTI_INTERP_EXTENSIONS;
    }

    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");
    }

    return _PyStatus_OK();
}


static void
init_interp_create_gil(PyThreadState *tstate, int gil)
{
    /* finalize_interp_delete() comment explains why _PyEval_FiniGIL() is
       only called here. */
    // XXX This is broken with a per-interpreter GIL.
    _PyEval_FiniGIL(tstate->interp);

    /* Auto-thread-state API */
    _PyGILState_SetTstate(tstate);

    int own_gil = (gil == PyInterpreterConfig_OWN_GIL);

    /* Create the GIL and take it */
    _PyEval_InitGIL(tstate, own_gil);
}

static int
builtins_dict_watcher(PyDict_WatchEvent event, PyObject *dict, PyObject *key, PyObject *new_value)
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
#ifdef _Py_TIER2
    if (interp->rare_events.builtin_dict < _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS) {
        _Py_Executors_InvalidateAll(interp, 1);
    }
#endif
    RARE_EVENT_INTERP_INC(interp, builtin_dict);
    return 0;
}

static PyStatus
pycore_create_interpreter(_PyRuntimeState *runtime,
                          const PyConfig *src_config,
                          PyThreadState **tstate_p)
{
    PyStatus status;
    PyInterpreterState *interp;
    status = _PyInterpreterState_New(NULL, &interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }
    assert(interp != NULL);
    assert(_Py_IsMainInterpreter(interp));
    _PyInterpreterState_SetWhence(interp, _PyInterpreterState_WHENCE_RUNTIME);
    interp->_ready = 1;

    /* Initialize the module dict watcher early, before any modules are created */
    if (_PyModule_InitModuleDictWatcher(interp) != 0) {
        return _PyStatus_ERR("failed to initialize module dict watcher");
    }

    status = _PyConfig_Copy(&interp->config, src_config);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    /* Auto-thread-state API */
    status = _PyGILState_Init(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT;
    // The main interpreter always has its own GIL and supports single-phase
    // init extensions.
    config.gil = PyInterpreterConfig_OWN_GIL;
    config.check_multi_interp_extensions = 0;
    status = init_interp_settings(interp, &config);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    // This could be done in init_interpreter() (in pystate.c) if it
    // didn't depend on interp->feature_flags being set already.
    status = _PyObject_InitState(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

#ifdef Py_STATS
    // initialize pystats.  This must be done after the settings are loaded.
    status = _PyStats_InterpInit(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }
#endif

    // 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();
    }

    status = _PyTraceMalloc_Init();
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    PyThreadState *tstate = _PyThreadState_New(interp,
                                               _PyThreadState_WHENCE_INIT);
    if (tstate == NULL) {
        return _PyStatus_ERR("can't make first thread");
    }
    runtime->main_tstate = tstate;
    _PyThreadState_Bind(tstate);

    init_interp_create_gil(tstate, config.gil);

    *tstate_p = tstate;
    return _PyStatus_OK();
}


static PyStatus
pycore_init_global_objects(PyInterpreterState *interp)
{
    PyStatus status;

    status = _PyUnicode_InitGlobalObjects(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    _PyUnicode_InitState(interp);

    if (_Py_IsMainInterpreter(interp)) {
        _Py_GetConstant_Init();
    }

    return _PyStatus_OK();
}


static PyStatus
pycore_init_types(PyInterpreterState *interp)
{
    PyStatus status;

    status = _PyTypes_InitTypes(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    status = _PyLong_InitTypes(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    status = _PyUnicode_InitTypes(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    status = _PyFloat_InitTypes(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    if (_PyExc_InitTypes(interp) < 0) {
        return _PyStatus_ERR("failed to initialize an exception type");
    }

    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;
    }

    status = _PyContext_Init(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    status = _PyXI_InitTypes(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    status = _PyInterpolation_InitTypes(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    status = _PyDateTime_InitTypes(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    return _PyStatus_OK();
}

static PyStatus
pycore_init_builtins(PyThreadState *tstate)
{
    PyInterpreterState *interp = tstate->interp;

    PyObject *bimod = _PyBuiltin_Init(interp);
    if (bimod == NULL) {
        goto error;
    }

    PyObject *modules = _PyImport_GetModules(interp);
    if (_PyImport_FixupBuiltin(tstate, bimod, "builtins", modules) < 0) {
        goto error;
    }

    PyObject *builtins_dict = PyModule_GetDict(bimod);
    if (builtins_dict == NULL) {
        goto error;
    }
    interp->builtins = Py_NewRef(builtins_dict);

    PyObject *isinstance = PyDict_GetItemWithError(builtins_dict, &_Py_ID(isinstance));
    if (!isinstance) {
        goto error;
    }
    interp->callable_cache.isinstance = isinstance;

    PyObject *len = PyDict_GetItemWithError(builtins_dict, &_Py_ID(len));
    if (!len) {
        goto error;
    }
    interp->callable_cache.len = len;

    PyObject *all = PyDict_GetItemWithError(builtins_dict, &_Py_ID(all));
    if (!all) {
        goto error;
    }

    PyObject *any = PyDict_GetItemWithError(builtins_dict, &_Py_ID(any));
    if (!any) {
        goto error;
    }

    interp->common_consts[CONSTANT_ASSERTIONERROR] = PyExc_AssertionError;
    interp->common_consts[CONSTANT_NOTIMPLEMENTEDERROR] = PyExc_NotImplementedError;
    interp->common_consts[CONSTANT_BUILTIN_TUPLE] = (PyObject *)&PyTuple_Type;
    interp->common_consts[CONSTANT_BUILTIN_ALL] = all;
    interp->common_consts[CONSTANT_BUILTIN_ANY] = any;
    interp->common_consts[CONSTANT_BUILTIN_LIST] = (PyObject *)&PyList_Type;
    interp->common_consts[CONSTANT_BUILTIN_SET] = (PyObject *)&PySet_Type;
    interp->common_consts[CONSTANT_NONE] = Py_None;
    interp->common_consts[CONSTANT_EMPTY_STR] =
        Py_GetConstantBorrowed(Py_CONSTANT_EMPTY_STR);
    interp->common_consts[CONSTANT_TRUE] = Py_True;
    interp->common_consts[CONSTANT_FALSE] = Py_False;
    interp->common_consts[CONSTANT_MINUS_ONE] =
        (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS - 1];
    for (int i = 0; i < NUM_COMMON_CONSTANTS; i++) {
        assert(interp->common_consts[i] != NULL);
    }

    PyObject *list_append = _PyType_Lookup(&PyList_Type, &_Py_ID(append));
    if (list_append == NULL) {
        goto error;
    }
    interp->callable_cache.list_append = list_append;

    PyObject *object__getattribute__ = _PyType_Lookup(&PyBaseObject_Type, &_Py_ID(__getattribute__));
    if (object__getattribute__ == NULL) {
        goto error;
    }
    interp->callable_cache.object__getattribute__ = object__getattribute__;

    if (_PyType_InitSlotDefs(interp) < 0) {
        return _PyStatus_ERR("failed to init slotdefs");
    }

    if (_PyBuiltins_AddExceptions(bimod) < 0) {
        return _PyStatus_ERR("failed to add exceptions to builtins");
    }

    interp->builtins_copy = PyDict_Copy(interp->builtins);
    if (interp->builtins_copy == NULL) {
        goto error;
    }
    Py_DECREF(bimod);

    if (_PyImport_InitDefaultImportFunc(interp) < 0) {
        goto error;
    }

    assert(!_PyErr_Occurred(tstate));
    return _PyStatus_OK();

error:
    Py_XDECREF(bimod);
    return _PyStatus_ERR("can't initialize builtins module");
}


static PyStatus
pycore_interp_init(PyThreadState *tstate)
{
    _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
    if (_tstate->c_stack_hard_limit == 0) {
        _Py_InitializeRecursionLimits(tstate);
    }
    PyInterpreterState *interp = tstate->interp;
    PyStatus status;
    PyObject *sysmod = NULL;

    // 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).
    status = pycore_init_global_objects(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    status = _PyCode_Init(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    status = _PyDtoa_Init(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    // The GC must be initialized before the first GC collection.
    status = _PyGC_Init(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    status = pycore_init_types(interp);
    if (_PyStatus_EXCEPTION(status)) {
        goto done;
    }

    if (_PyWarnings_InitState(interp) < 0) {
        return _PyStatus_ERR("can't initialize warnings");
    }

    status = _PyAtExit_Init(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    status = _PySys_Create(tstate, &sysmod);
    if (_PyStatus_EXCEPTION(status)) {
        goto done;
    }

    status = pycore_init_builtins(tstate);
    if (_PyStatus_EXCEPTION(status)) {
        goto done;
    }

    status = _PyXI_Init(interp);
    if (_PyStatus_EXCEPTION(status)) {
        goto done;
    }

    const PyConfig *config = _PyInterpreterState_GetConfig(interp);

    status = _PyImport_InitCore(tstate, sysmod, config->_install_importlib);
    if (_PyStatus_EXCEPTION(status)) {
        goto done;
    }

done:
    /* sys.modules['sys'] contains a strong reference to the module */
    Py_XDECREF(sysmod);
    return status;
}


static PyStatus
pyinit_config(_PyRuntimeState *runtime,
              PyThreadState **tstate_p,
              const PyConfig *config)
{
    PyStatus status = pycore_init_runtime(runtime, config);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    PyThreadState *tstate;
    status = pycore_create_interpreter(runtime, config, &tstate);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }
    *tstate_p = tstate;

    status = pycore_interp_init(tstate);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    /* Only when we get here is the runtime core fully initialized */
    _PyRuntimeState_SetCoreInitialized(runtime, 1);
    return _PyStatus_OK();
}


PyStatus
_Py_PreInitializeFromPyArgv(const PyPreConfig *src_config, const _PyArgv *args)
{
    PyStatus status;

    if (src_config == NULL) {
        return _PyStatus_ERR("preinitialization config is NULL");
    }

    status = _PyRuntime_Initialize();
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }
    _PyRuntimeState *runtime = &_PyRuntime;

    if (runtime->preinitialized) {
        /* If it's already configured: ignored the new configuration */
        return _PyStatus_OK();
    }

    /* Note: preinitializing remains 1 on error, it is only set to 0
       at exit on success. */
    runtime->preinitializing = 1;

    PyPreConfig config;

    status = _PyPreConfig_InitFromPreConfig(&config, src_config);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    status = _PyPreConfig_Read(&config, args);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    status = _PyPreConfig_Write(&config);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    runtime->preinitializing = 0;
    runtime->preinitialized = 1;
    return _PyStatus_OK();
}


PyStatus
Py_PreInitializeFromBytesArgs(const PyPreConfig *src_config, Py_ssize_t argc, char **argv)
{
    _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv};
    return _Py_PreInitializeFromPyArgv(src_config, &args);
}


PyStatus
Py_PreInitializeFromArgs(const PyPreConfig *src_config, Py_ssize_t argc, wchar_t **argv)
{
    _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv};
    return _Py_PreInitializeFromPyArgv(src_config, &args);
}


PyStatus
Py_PreInitialize(const PyPreConfig *src_config)
{
    return _Py_PreInitializeFromPyArgv(src_config, NULL);
}


PyStatus
_Py_PreInitializeFromConfig(const PyConfig *config,
                            const _PyArgv *args)
{
    assert(config != NULL);

    PyStatus status = _PyRuntime_Initialize();
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }
    _PyRuntimeState *runtime = &_PyRuntime;

    if (runtime->preinitialized) {
        /* Already initialized: do nothing */
        return _PyStatus_OK();
    }

    PyPreConfig preconfig;

    _PyPreConfig_InitFromConfig(&preconfig, config);

    if (!config->parse_argv) {
        return Py_PreInitialize(&preconfig);
    }
    else if (args == NULL) {
        _PyArgv config_args = {
            .use_bytes_argv = 0,
            .argc = config->argv.length,
            .wchar_argv = config->argv.items};
        return _Py_PreInitializeFromPyArgv(&preconfig, &config_args);
    }
    else {
        return _Py_PreInitializeFromPyArgv(&preconfig, args);
    }
}


/* 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)
 */
static PyStatus
pyinit_core(_PyRuntimeState *runtime,
            const PyConfig *src_config,
            PyThreadState **tstate_p)
{
    PyStatus status;

    status = _Py_PreInitializeFromConfig(src_config, NULL);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    PyConfig config;
    PyConfig_InitPythonConfig(&config);

    status = _PyConfig_Copy(&config, src_config);
    if (_PyStatus_EXCEPTION(status)) {
        goto done;
    }

    // Read the configuration, but don't compute the path configuration
    // (it is computed in the main init).
    status = _PyConfig_Read(&config, 0);
    if (_PyStatus_EXCEPTION(status)) {
        goto done;
    }

    if (!runtime->core_initialized) {
        status = pyinit_config(runtime, tstate_p, &config);
    }
    else {
        status = pyinit_core_reconfigure(runtime, tstate_p, &config);
    }
    if (_PyStatus_EXCEPTION(status)) {
        goto done;
    }

done:
    PyConfig_Clear(&config);
    return status;
}


/* Py_Initialize() has already been called: update the main interpreter
   configuration. Example of bpo-34008: Py_Main() called after
   Py_Initialize(). */
static PyStatus
pyinit_main_reconfigure(PyThreadState *tstate)
{
    if (interpreter_update_config(tstate, 0) < 0) {
        return _PyStatus_ERR("fail to reconfigure Python");
    }
    return _PyStatus_OK();
}


#ifdef Py_DEBUG
// Equivalent to the Python code:
//
//     for part in attr.split('.'):
//         obj = getattr(obj, part)
static PyObject*
presite_resolve_name(PyObject *obj, PyObject *attr)
{
    obj = Py_NewRef(obj);
    attr = Py_NewRef(attr);
    PyObject *res;

    while (1) {
        Py_ssize_t len = PyUnicode_GET_LENGTH(attr);
        Py_ssize_t pos = PyUnicode_FindChar(attr, '.', 0, len, 1);
        if (pos < 0) {
            break;
        }

        PyObject *name = PyUnicode_Substring(attr, 0, pos);
        if (name == NULL) {
            goto error;
        }
        res = PyObject_GetAttr(obj, name);
        Py_DECREF(name);
        if (res == NULL) {
            goto error;
        }
        Py_SETREF(obj, res);

        PyObject *suffix = PyUnicode_Substring(attr, pos + 1, len);
        if (suffix == NULL) {
            goto error;
        }
        Py_SETREF(attr, suffix);
    }

    res = PyObject_GetAttr(obj, attr);
    Py_DECREF(obj);
    Py_DECREF(attr);
    return res;

error:
    Py_DECREF(obj);
    Py_DECREF(attr);
    return NULL;
}


static void
run_presite(PyThreadState *tstate)
{
    PyInterpreterState *interp = tstate->interp;
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);

    if (!config->run_presite) {
        return;
    }

    PyObject *presite = PyUnicode_FromWideChar(config->run_presite, -1);
    if (presite == NULL) {
        fprintf(stderr, "Could not convert pre-site command to Unicode\n");
        _PyErr_Print(tstate);
        return;
    }

    // Accept "mod_name" and "mod_name:func_name" entry point syntax
    Py_ssize_t len = PyUnicode_GET_LENGTH(presite);
    Py_ssize_t pos = PyUnicode_FindChar(presite, ':', 0, len, 1);
    PyObject *mod_name = NULL;
    PyObject *func_name = NULL;
    PyObject *module = NULL;
    if (pos > 0) {
        mod_name = PyUnicode_Substring(presite, 0, pos);
        if (mod_name == NULL) {
            goto error;
        }

        func_name = PyUnicode_Substring(presite, pos + 1, len);
        if (func_name == NULL) {
            goto error;
        }
    }
    else {
        mod_name = Py_NewRef(presite);
    }

    // mod_name can contain dots (ex: "math.integer")
    module = PyImport_Import(mod_name);
    if (module == NULL) {
        goto error;
    }

    if (func_name != NULL) {
        PyObject *func = presite_resolve_name(module, func_name);
        if (func == NULL) {
            goto error;
        }

        PyObject *res = PyObject_CallNoArgs(func);
        Py_DECREF(func);
        if (res == NULL) {
            goto error;
        }
        Py_DECREF(res);
    }

    Py_DECREF(presite);
    Py_DECREF(mod_name);
    Py_XDECREF(func_name);
    Py_DECREF(module);
    return;

error:
    fprintf(stderr, "pre-site failed:\n");
    _PyErr_Print(tstate);

    Py_DECREF(presite);
    Py_XDECREF(mod_name);
    Py_XDECREF(func_name);
    Py_XDECREF(module);
}
#endif


static PyStatus
init_interp_main(PyThreadState *tstate)
{
    assert(!_PyErr_Occurred(tstate));

    PyStatus status;
    int is_main_interp = _Py_IsMainInterpreter(tstate->interp);
    PyInterpreterState *interp = tstate->interp;
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);

    if (!config->_install_importlib) {
        /* 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.
         */
        if (is_main_interp) {
            _PyRuntimeState_SetInitialized(interp->runtime, 1);
        }
        return _PyStatus_OK();
    }

    // Initialize the import-related configuration.
    status = _PyConfig_InitImportConfig(&interp->config);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    if (interpreter_update_config(tstate, 1) < 0) {
        return _PyStatus_ERR("failed to update the Python config");
    }

    status = _PyImport_InitExternal(tstate);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    if (is_main_interp) {
        /* initialize the faulthandler module */
        status = _PyFaulthandler_Init(config->faulthandler);
        if (_PyStatus_EXCEPTION(status)) {
            return status;
        }
    }

    status = _PyUnicode_InitEncodings(tstate);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    if (is_main_interp) {
        if (_PySignal_Init(config->install_signal_handlers) < 0) {
            return _PyStatus_ERR("can't initialize signals");
        }

        if (config->tracemalloc) {
           if (_PyTraceMalloc_Start(config->tracemalloc) < 0) {
                return _PyStatus_ERR("can't start tracemalloc");
            }
        }

#ifdef PY_HAVE_PERF_TRAMPOLINE
        if (config->perf_profiling) {
            _PyPerf_Callbacks *cur_cb;
            if (config->perf_profiling == 1) {
                cur_cb = &_Py_perfmap_callbacks;
            }
            else {
                cur_cb = &_Py_perfmap_jit_callbacks;
            }
            if (_PyPerfTrampoline_SetCallbacks(cur_cb) < 0 ||
                    _PyPerfTrampoline_Init(config->perf_profiling) < 0) {
                return _PyStatus_ERR("can't initialize the perf trampoline");
            }
        }
#endif
    }

    status = init_sys_streams(tstate);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    status = init_set_builtins_open();
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

#ifdef __ANDROID__
    status = init_android_streams(tstate);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }
#endif
#if defined(__APPLE__) && HAS_APPLE_SYSTEM_LOG
    if (config->use_system_logger) {
        status = init_apple_streams(tstate);
        if (_PyStatus_EXCEPTION(status)) {
            return status;
        }
    }
#endif

#ifdef Py_DEBUG
    run_presite(tstate);
#endif

    status = add_main_module(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    if (is_main_interp) {
        /* Initialize warnings. */
        PyObject *warnoptions;
        if (PySys_GetOptionalAttrString("warnoptions", &warnoptions) < 0) {
            return _PyStatus_ERR("can't initialize warnings");
        }
        if (warnoptions != NULL && PyList_Check(warnoptions) &&
            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);
        }
        Py_XDECREF(warnoptions);
    }

    if (config->site_import) {
        status = init_import_site();
        if (_PyStatus_EXCEPTION(status)) {
            return status;
        }
    }

    // Initialize lazy imports based on configuration. Do this after site
    // module is imported to avoid circular imports during startup.
    if (config->lazy_imports != -1) {
        PyImport_LazyImportsMode lazy_mode;
        if (config->lazy_imports == 1) {
            lazy_mode = PyImport_LAZY_ALL;
        }
        else {
            lazy_mode = PyImport_LAZY_NONE;
        }
        if (PyImport_SetLazyImportsMode(lazy_mode) < 0) {
            return _PyStatus_ERR("failed to set lazy imports mode");
        }
    }
    // If config->lazy_imports == -1, use the default mode, no change needed.

    if (is_main_interp) {
#ifndef MS_WINDOWS
        emit_stderr_warning_for_legacy_locale(interp->runtime);
#endif
    }

    // Turn on experimental tier 2 (uops-based) optimizer
    // This is also needed when the JIT is enabled
#ifdef _Py_TIER2
    if (is_main_interp) {
        int enabled = 1;
#if _Py_TIER2 & 2
        enabled = 0;
#endif
        char *env = Py_GETENV("PYTHON_JIT");
        if (env && *env != '\0') {
            // PYTHON_JIT=0|1 overrides the default
            enabled = *env != '0';
        }
        if (enabled) {
#ifdef _Py_JIT
            // perf profiler works fine with tier 2 interpreter, so
            // only checking for a "real JIT".
            if (config->perf_profiling > 0) {
                (void)PyErr_WarnEx(
                    PyExc_RuntimeWarning,
                    "JIT deactivated as perf profiling support is active",
                    0);
            } else
#endif
            {
                interp->jit = true;
            }
        }
    }
#endif

    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]");
            }
        }
    }


    interp->dict_state.watchers[0] = &builtins_dict_watcher;
    if (PyDict_Watch(0, interp->builtins) != 0) {
        return _PyStatus_ERR("failed to set builtin dict watcher");
    }

    assert(!_PyErr_Occurred(tstate));

    if (is_main_interp) {
        _PyRuntimeState_SetInitialized(interp->runtime, 1);
    }

    return _PyStatus_OK();
}


/* 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 (!_PyRuntimeState_GetCoreInitialized(interp->runtime)) {
        return _PyStatus_ERR("runtime core not initialized");
    }

    if (_PyRuntimeState_GetInitialized(interp->runtime)) {
        return pyinit_main_reconfigure(tstate);
    }

    PyStatus status = init_interp_main(tstate);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }
    return _PyStatus_OK();
}


PyStatus
Py_InitializeFromConfig(const PyConfig *config)
{
    if (config == NULL) {
        return _PyStatus_ERR("initialization config is NULL");
    }

    PyStatus status;

    status = _PyRuntime_Initialize();
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }
    _PyRuntimeState *runtime = &_PyRuntime;

    PyThreadState *tstate = NULL;
    status = pyinit_core(runtime, config, &tstate);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }
    config = _PyInterpreterState_GetConfig(tstate->interp);

    if (config->_init_main) {
        status = pyinit_main(tstate);
        if (_PyStatus_EXCEPTION(status)) {
            return status;
        }
    }

    return _PyStatus_OK();
}


void
Py_InitializeEx(int install_sigs)
{
    if (Py_IsInitialized()) {
        /* bpo-33932: Calling Py_Initialize() twice does nothing. */
        return;
    }

    PyStatus status;
    PyConfig config;
    _PyConfig_InitCompatConfig(&config);

    config.install_signal_handlers = install_sigs;

    status = Py_InitializeFromConfig(&config);
    PyConfig_Clear(&config);
    if (_PyStatus_EXCEPTION(status)) {
        Py_ExitStatusException(status);
    }
}

void
Py_Initialize(void)
{
    Py_InitializeEx(1);
}


PyStatus
_Py_InitializeMain(void)
{
    PyStatus status = _PyRuntime_Initialize();
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }
    PyThreadState *tstate = _PyThreadState_GET();
    return pyinit_main(tstate);
}


static void
finalize_modules_delete_special(PyThreadState *tstate, int verbose)
{
    // List of names to clear in sys
    static const char * const sys_deletes[] = {
        "path", "argv", "ps1", "ps2", "last_exc",
        "last_type", "last_value", "last_traceback",
        "__interactivehook__",
        // path_hooks and path_importer_cache are cleared
        // by _PyImport_FiniExternal().
        // XXX Clear meta_path in _PyImport_FiniCore().
        "meta_path",
        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) {
        PyErr_FormatUnraisable("Exception ignored while "
                               "setting builtin variable _");
    }

    const char * const *p;
    for (p = sys_deletes; *p != NULL; p++) {
        if (_PySys_ClearAttrString(interp, *p, verbose) < 0) {
            PyErr_FormatUnraisable("Exception ignored while "
                                   "clearing sys.%s", *p);
        }
    }
    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);
        }
        PyObject *value;
        if (PyDict_GetItemStringRef(interp->sysdict, orig_name, &value) < 0) {
            PyErr_FormatUnraisable("Exception ignored while "
                                   "restoring sys.%s", name);
        }
        if (value == NULL) {
            value = Py_NewRef(Py_None);
        }
        if (PyDict_SetItemString(interp->sysdict, name, value) < 0) {
            PyErr_FormatUnraisable("Exception ignored while "
                                   "restoring sys.%s", name);
        }
        Py_DECREF(value);
    }
}


static PyObject*
finalize_remove_modules(PyObject *modules, int verbose)
{
    PyObject *weaklist = PyList_New(0);
    if (weaklist == NULL) {
        PyErr_FormatUnraisable("Exception ignored while removing modules");
    }

#define STORE_MODULE_WEAKREF(name, mod) \
        if (weaklist != NULL) { \
            PyObject *wr = PyWeakref_NewRef(mod, NULL); \
            if (wr) { \
                PyObject *tup = _PyTuple_FromPair(name, wr); \
                if (!tup || PyList_Append(weaklist, tup) < 0) { \
                    PyErr_FormatUnraisable("Exception ignored while removing modules"); \
                } \
                Py_XDECREF(tup); \
                Py_DECREF(wr); \
            } \
            else { \
                PyErr_FormatUnraisable("Exception ignored while removing modules"); \
            } \
        }

#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) { \
                PyErr_FormatUnraisable("Exception ignored while removing modules"); \
            } \
        }

    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) {
            PyErr_FormatUnraisable("Exception ignored while removing modules");
        }
        else {
            PyObject *key;
            while ((key = PyIter_Next(iterator))) {
                PyObject *value = PyObject_GetItem(modules, key);
                if (value == NULL) {
                    PyErr_FormatUnraisable("Exception ignored while removing modules");
                    Py_DECREF(key);
                    continue;
                }
                CLEAR_MODULE(key, value);
                Py_DECREF(value);
                Py_DECREF(key);
            }
            if (PyErr_Occurred()) {
                PyErr_FormatUnraisable("Exception ignored while removing modules");
            }
            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 {
        if (PyObject_CallMethodNoArgs(modules, &_Py_ID(clear)) == NULL) {
            PyErr_FormatUnraisable("Exception ignored while clearing sys.modules");
        }
    }
}


static void
finalize_restore_builtins(PyThreadState *tstate)
{
    PyInterpreterState *interp = tstate->interp;
    PyObject *dict = PyDict_Copy(interp->builtins);
    if (dict == NULL) {
        PyErr_FormatUnraisable("Exception ignored while restoring builtins");
    }
    PyDict_Clear(interp->builtins);
    if (PyDict_Update(interp->builtins, interp->builtins_copy)) {
        PyErr_FormatUnraisable("Exception ignored while restoring builtins");
    }
    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);
        PyObject *mod = _PyWeakref_GET_REF(PyTuple_GET_ITEM(tup, 1));
        if (mod == NULL) {
            continue;
        }
        assert(PyModule_Check(mod));
        PyObject *dict = _PyModule_GetDict(mod);  // borrowed reference
        if (dict == interp->builtins || dict == interp->sysdict) {
            Py_DECREF(mod);
            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 */
// XXX Move most of this to import.c.
static void
finalize_modules(PyThreadState *tstate)
{
    PyInterpreterState *interp = tstate->interp;

    // Invalidate all executors and turn off JIT:
    interp->jit = false;
    interp->compiling = false;
#ifdef _Py_TIER2
    _Py_Executors_InvalidateAll(interp, 0);
    PyMem_Free(interp->executor_blooms);
    PyMem_Free(interp->executor_ptrs);
    interp->executor_blooms = NULL;
    interp->executor_ptrs = NULL;
    interp->executor_count = 0;
    interp->executor_capacity = 0;
#endif

    // Stop watching __builtin__ modifications
    if (PyDict_Unwatch(0, interp->builtins) < 0) {
        // might happen if interp is cleared before watching the __builtin__
        PyErr_Clear();
    }
    PyObject *modules = _PyImport_GetModules(interp);
    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.
    _PyGC_DumpShutdownStats(interp);

    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)
    _PyImport_ClearModulesByIndex(interp);

    // Clear the dict of lazily loaded module nname to submodule names
    _PyImport_ClearLazyModules(interp);

    // Clear and delete the modules directory.  Actual modules will
    // still be there only if imported during the execution of some
    // destructor.
    _PyImport_ClearModules(interp);

    // Collect garbage once more
    _PyGC_CollectNoFail(tstate);
}


/* 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;
}


static int
flush_std_files(void)
{
    PyObject *file;
    int status = 0;

    if (PySys_GetOptionalAttr(&_Py_ID(stdout), &file) < 0) {
        status = -1;
    }
    else if (file != NULL && file != Py_None && !file_is_closed(file)) {
        if (_PyFile_Flush(file) < 0) {
            status = -1;
        }
    }
    if (status < 0) {
        PyErr_FormatUnraisable("Exception ignored while flushing sys.stdout");
    }
    Py_XDECREF(file);

    if (PySys_GetOptionalAttr(&_Py_ID(stderr), &file) < 0) {
        PyErr_Clear();
        status = -1;
    }
    else if (file != NULL && file != Py_None && !file_is_closed(file)) {
        if (_PyFile_Flush(file) < 0) {
            PyErr_Clear();
            status = -1;
        }
    }
    Py_XDECREF(file);

    return status;
}

/* 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.

*/


static void
finalize_interp_types(PyInterpreterState *interp)
{
    _PyTypes_FiniExtTypes(interp);
    _PyUnicode_FiniTypes(interp);
    _PySys_FiniTypes(interp);
    _PyXI_FiniTypes(interp);
    _PyExc_Fini(interp);
    _PyFloat_FiniType(interp);
    _PyLong_FiniTypes(interp);
    _PyThread_FiniType(interp);
    // XXX fini collections module static types (_PyStaticType_Dealloc())
    // XXX fini IO module static types (_PyStaticType_Dealloc())
    _PyErr_FiniTypes(interp);
    _PyTypes_FiniTypes(interp);

    _PyTypes_Fini(interp);
#ifdef Py_GIL_DISABLED
    _PyObject_FinalizeUniqueIdPool(interp);
#endif

    _PyCode_Fini(interp);

    // Call _PyUnicode_ClearInterned() before _PyDict_Fini() since it uses
    // a dict internally.
    _PyUnicode_ClearInterned(interp);

    _PyUnicode_Fini(interp);

#ifndef Py_GIL_DISABLED
    // With Py_GIL_DISABLED:
    // the freelists for the current thread state have already been cleared.
    struct _Py_freelists *freelists = _Py_freelists_GET();
    _PyObject_ClearFreeLists(freelists, 1);
#endif

#ifdef Py_DEBUG
    _PyStaticObjects_CheckRefcnt(interp);
#endif
}


static void
finalize_interp_clear(PyThreadState *tstate)
{
    int is_main_interp = _Py_IsMainInterpreter(tstate->interp);

    _PyXI_Fini(tstate->interp);
    _PyExc_ClearExceptionGroupType(tstate->interp);
    _Py_clear_generic_types(tstate->interp);
    _PyTypes_FiniCachedDescriptors(tstate->interp);

    /* Clear interpreter state and all thread states */
    _PyInterpreterState_Clear(tstate);

    /* 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);
    }

    if (is_main_interp) {
        _Py_HashRandomization_Fini();
        _PyArg_Fini();
        _Py_ClearFileSystemEncoding();
        _PyPerfTrampoline_Fini();
    }

    finalize_interp_types(tstate->interp);

    /* Finalize dtoa at last so that finalizers calling repr of float doesn't crash */
    _PyDtoa_Fini(tstate->interp);

    /* Free any delayed free requests immediately */
    _PyMem_FiniDelayed(tstate->interp);

    /* finalize_interp_types may allocate Python objects so we may need to
       abandon mimalloc segments again */
    _PyThreadState_ClearMimallocHeaps(tstate);
}


static void
finalize_interp_delete(PyInterpreterState *interp)
{
    /* Cleanup auto-thread-state */
    _PyGILState_Fini(interp);

    /* 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. */

    PyInterpreterState_Delete(interp);
}


/* Conceptually, there isn't a good reason for Py_Finalize()
   to be called in any other thread than the one where Py_Initialize()
   was called.  Consequently, it would make sense to fail if the thread
   or thread state (or interpreter) don't match.  However, such
   constraints have never been enforced, and, as unlikely as it may be,
   there may be users relying on the unconstrained behavior.  Thus,
   we do our best here to accommodate that possibility. */

static PyThreadState *
resolve_final_tstate(_PyRuntimeState *runtime)
{
    PyThreadState *main_tstate = runtime->main_tstate;
    assert(main_tstate != NULL);
    assert(main_tstate->thread_id == runtime->main_thread);
    PyInterpreterState *main_interp = _PyInterpreterState_Main();
    assert(main_tstate->interp == main_interp);

    PyThreadState *tstate = _PyThreadState_GET();
    if (_Py_IsMainThread()) {
        if (tstate != main_tstate) {
            /* This implies that Py_Finalize() was called while
               a non-main interpreter was active or while the main
               tstate was temporarily swapped out with another.
               Neither case should be allowed, but, until we get around
               to fixing that (and Py_Exit()), we're letting it go. */
            (void)PyThreadState_Swap(main_tstate);
        }
    }
    else {
        /* This is another unfortunate case where Py_Finalize() was
           called when it shouldn't have been.  We can't simply switch
           over to the main thread.  At the least, however, we can make
           sure the main interpreter is active. */
        if (!_Py_IsMainInterpreter(tstate->interp)) {
            /* We don't go to the trouble of updating runtime->main_tstate
               since it will be dead soon anyway. */
            main_tstate =
                _PyThreadState_New(main_interp, _PyThreadState_WHENCE_FINI);
            if (main_tstate != NULL) {
                _PyThreadState_Bind(main_tstate);
                (void)PyThreadState_Swap(main_tstate);
            }
            else {
                /* Fall back to the current tstate.  It's better than nothing. */
                // XXX No it's not
                main_tstate = tstate;
            }
        }
    }
    assert(main_tstate != NULL);

    /* We might want to warn if main_tstate->current_frame != NULL. */

    return main_tstate;
}

#ifdef Py_GIL_DISABLED
#define ASSERT_WORLD_STOPPED(interp) assert(interp->runtime->stoptheworld.world_stopped)
#else
#define ASSERT_WORLD_STOPPED(interp)
#endif

static int
interp_has_threads(PyInterpreterState *interp)
{
    /* This needs to check for non-daemon threads only, otherwise we get stuck
     * in an infinite loop. */
    assert(interp != NULL);
    ASSERT_HEAD_IS_LOCKED(interp->runtime);
    assert(interp->threads.head != NULL);
    if (interp->threads.head->next == NULL) {
        // No other threads active, easy way out.
        return 0;
    }

    _Py_FOR_EACH_TSTATE_UNLOCKED(interp, tstate) {
        if (tstate->_whence == _PyThreadState_WHENCE_THREADING) {
            return 1;
        }
    }

    return 0;
}

static int
interp_has_pending_calls(PyInterpreterState *interp)
{
    assert(interp != NULL);
    ASSERT_WORLD_STOPPED(interp);
    return interp->ceval.pending.npending != 0;
}

static int
interp_has_atexit_callbacks(PyInterpreterState *interp)
{
    assert(interp != NULL);
    assert(interp->atexit.callbacks != NULL);
    ASSERT_WORLD_STOPPED(interp);
    assert(PyList_CheckExact(interp->atexit.callbacks));
    return PyList_GET_SIZE(interp->atexit.callbacks) != 0;
}

static int
runtime_has_subinterpreters(_PyRuntimeState *runtime)
{
    assert(runtime != NULL);
    PyInterpreterState *interp = runtime->interpreters.head;
    return interp->next != NULL;
}

static void
make_pre_finalization_calls(PyThreadState *tstate, int subinterpreters)
{
    assert(tstate != NULL);
    PyInterpreterState *interp = tstate->interp;
    assert(_Py_atomic_load_uintptr(&interp->finalization_guards) != _PyInterpreterGuard_GUARDS_NOT_ALLOWED);
    /* Each of these functions can start one another, e.g. a pending call
     * could start a thread or vice versa. To ensure that we properly clean
     * call everything, we run these in a loop until none of them run anything. */
    for (;;) {
        assert(!interp->runtime->stoptheworld.world_stopped);

        // Wrap up existing "threading"-module-created, non-daemon threads.
        wait_for_thread_shutdown(tstate);

        // Make any remaining pending calls.
        _Py_FinishPendingCalls(tstate);

        /* 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
        * runtime is uninitialized until after the exit funcs have run.
        * 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.
        */

        _PyAtExit_Call(tstate->interp);

        if (subinterpreters) {
            /* Clean up any lingering subinterpreters.
             * Two preconditions need to be met here:
             * 1. This has to happen before _PyRuntimeState_SetFinalizing is
             *    called, or else threads might get prematurely blocked.
             * 2. The world must not be stopped, as finalizers can run.
             */
            finalize_subinterpreters();
        }

        // This is used as a throttle to prevent constant spinning while
        // on finalization guards.
        for (;;) {
            uintptr_t num_guards = _Py_atomic_load_uintptr(&interp->finalization_guards);
            if (num_guards == 0) {
                break;
            }

            int ret = _PyParkingLot_Park(&interp->finalization_guards,
                                         &num_guards, sizeof(num_guards), -1,
                                         NULL, /*detach=*/1);
            if (ret == Py_PARK_OK) {
                break;
            }
            else if (ret == Py_PARK_INTR) {
                if (PyErr_CheckSignals() < 0) {
                    int fatal = PyErr_ExceptionMatches(PyExc_KeyboardInterrupt);
                    PyErr_FormatUnraisable("Exception ignored while waiting on finalization guards");
                    if (fatal) {
                        fputs("Interrupted while waiting on finalization guards\n", stderr);
                        exit(1);
                    }
                }
                assert(!PyErr_Occurred());
            }
            else {
                assert(ret == Py_PARK_AGAIN);
            }
        }

        /* Stop the world to prevent other threads from creating threads or
         * atexit callbacks. On the default build, this is simply locked by
         * the GIL. For pending calls, we acquire the dedicated mutex, because
         * Py_AddPendingCall() can be called without an attached thread state.
         */
        PyMutex_Lock(&interp->ceval.pending.mutex);
        _PyEval_StopTheWorldAll(interp->runtime);

        HEAD_LOCK(interp->runtime);
        int has_subinterpreters = subinterpreters
                                    ? runtime_has_subinterpreters(interp->runtime)
                                    : 0;
        uintptr_t guards_expected = 0;
        int should_continue = (interp_has_threads(interp)
                              || interp_has_atexit_callbacks(interp)
                              || interp_has_pending_calls(interp)
                              || has_subinterpreters);

        if (!should_continue) {
            // We only want to prevent new guards once we're sure that we
            // won't be running another pre-finalization cycle.
            if (_Py_atomic_compare_exchange_uintptr(&interp->finalization_guards,
                                                    &guards_expected,
                                                    _PyInterpreterGuard_GUARDS_NOT_ALLOWED) == 1) {
                HEAD_UNLOCK(interp->runtime);
                break;
            }
        }
        HEAD_UNLOCK(interp->runtime);
        _PyEval_StartTheWorldAll(interp->runtime);
        PyMutex_Unlock(&interp->ceval.pending.mutex);
    }
    assert(PyMutex_IsLocked(&interp->ceval.pending.mutex));
    assert(_Py_atomic_load_uintptr(&interp->finalization_guards) == _PyInterpreterGuard_GUARDS_NOT_ALLOWED);
    ASSERT_WORLD_STOPPED(interp);
}

static int
_Py_Finalize(_PyRuntimeState *runtime)
{
    int status = 0;

    /* Bail out early if already finalized (or never initialized). */
    if (!_PyRuntimeState_GetInitialized(runtime)) {
        return status;
    }

    /* Get final thread state pointer. */
    PyThreadState *tstate = resolve_final_tstate(runtime);

    // Block some operations.
    tstate->interp->finalizing = 1;

    // This call stops the world and takes the pending calls lock.
    make_pre_finalization_calls(tstate, /*subinterpreters=*/1);

    assert(_PyThreadState_GET() == tstate);

    /* Copy the core config, PyInterpreterState_Delete() free
       the core config memory */
#ifdef Py_REF_DEBUG
    int show_ref_count = tstate->interp->config.show_ref_count;
#endif
#ifdef Py_TRACE_REFS
    int dump_refs = tstate->interp->config.dump_refs;
    wchar_t *dump_refs_file = tstate->interp->config.dump_refs_file;
#endif
#ifdef WITH_PYMALLOC
    int malloc_stats = tstate->interp->config.malloc_stats;
#endif

    /* Ensure that remaining threads are detached */
    ASSERT_WORLD_STOPPED(tstate->interp);

    /* Remaining daemon threads will be trapped in PyThread_hang_thread
       when they attempt to take the GIL (ex: PyEval_RestoreThread()). */
    _PyInterpreterState_SetFinalizing(tstate->interp, tstate);
    _PyRuntimeState_SetFinalizing(runtime, tstate);
    _PyRuntimeState_SetInitialized(runtime, 0);
    _PyRuntimeState_SetCoreInitialized(runtime, 0);

    // XXX Call something like _PyImport_Disable() here?

    /* Remove the state of all threads of the interpreter, except for the
       current thread. In practice, only daemon threads should still be alive,
       except if wait_for_thread_shutdown() has been cancelled by CTRL+C.
       We start the world once we are the only thread state left,
       before we call destructors. */
    PyThreadState *list = _PyThreadState_RemoveExcept(tstate);
    for (PyThreadState *p = list; p != NULL; p = p->next) {
        _PyThreadState_SetShuttingDown(p);
    }
    _PyEval_StartTheWorldAll(runtime);
    PyMutex_Unlock(&tstate->interp->ceval.pending.mutex);

    /* 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 hang in
       _PyThreadState_HangThread. */
    _PyThreadState_DeleteList(list, /*is_after_fork=*/0);

    /* 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).

    /* Flush sys.stdout and sys.stderr */
    if (flush_std_files() < 0) {
        status = -1;
    }

    /* Disable signal handling */
    _PySignal_Fini();

    /* 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.
     */
    PyGC_Collect();

    /* Destroy all modules */
    _PyImport_FiniExternal(tstate->interp);
    finalize_modules(tstate);

    /* Print debug stats if any */
    _PyEval_Fini();


    /* Flush sys.stdout and sys.stderr (again, in case more was printed) */
    if (flush_std_files() < 0) {
        status = -1;
    }

    /* 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
    _PyGC_CollectIfEnabled();
#endif

    /* Disable tracemalloc after all Python objects have been destroyed,
       so it is possible to use tracemalloc in objects destructor. */
    _PyTraceMalloc_Fini();

    /* Finalize any remaining import state */
    // XXX Move these up to where finalize_modules() is currently.
    _PyImport_FiniCore(tstate->interp);
    _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.
     */

    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);
        }
    }

    if (dump_refs) {
        _Py_PrintReferences(tstate->interp, stderr);
    }

    if (dump_refs_fp != NULL) {
        _Py_PrintReferences(tstate->interp, dump_refs_fp);
    }
#endif /* Py_TRACE_REFS */

    /* 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.

    finalize_interp_clear(tstate);

#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
     * above by _Py_PrintReferences. */
    if (dump_refs) {
        _Py_PrintReferenceAddresses(tstate->interp, stderr);
    }
    if (dump_refs_fp != NULL) {
        _Py_PrintReferenceAddresses(tstate->interp, dump_refs_fp);
        fclose(dump_refs_fp);
    }
#endif /* Py_TRACE_REFS */

#ifdef WITH_PYMALLOC
    if (malloc_stats) {
        _PyObject_DebugMallocStats(stderr);
    }
#endif

    finalize_interp_delete(tstate->interp);

#ifdef Py_REF_DEBUG
    if (show_ref_count) {
        _PyDebug_PrintTotalRefs();
    }
    _Py_FinalizeRefTotal(runtime);
#endif
    _Py_FinalizeAllocatedBlocks(runtime);

    call_ll_exitfuncs(runtime);

    _PyRuntime_Finalize();
    return status;
}

int
Py_FinalizeEx(void)
{
    return _Py_Finalize(&_PyRuntime);
}

void
Py_Finalize(void)
{
    (void)_Py_Finalize(&_PyRuntime);
}


/* 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.

*/

static PyStatus
new_interpreter(PyThreadState **tstate_p,
                const PyInterpreterConfig *config, long whence)
{
    PyStatus status;

    status = _PyRuntime_Initialize();
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }
    _PyRuntimeState *runtime = &_PyRuntime;

    if (!_PyRuntimeState_GetInitialized(runtime)) {
        return _PyStatus_ERR("Py_Initialize must be called first");
    }

    /* Issue #10915, #15751: The GIL API doesn't work with multiple
       interpreters: disable PyGILState_Check(). */
    _Py_atomic_store_int_relaxed(&runtime->gilstate.check_enabled, 0);

    // XXX Might new_interpreter() have been called without the GIL held?
    PyThreadState *save_tstate = _PyThreadState_GET();
    PyThreadState *tstate = NULL;
    PyInterpreterState *interp;
    status = _PyInterpreterState_New(save_tstate, &interp);
    if (interp == NULL) {
        goto error;
    }
    _PyInterpreterState_SetWhence(interp, whence);
    interp->_ready = 1;

    /* Initialize the module dict watcher early, before any modules are created */
    if (_PyModule_InitModuleDictWatcher(interp) != 0) {
        goto error;
    }

    /* 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). */
    if (save_tstate != NULL) {
        _PyThreadState_Detach(save_tstate);
    }

    /* Copy the current interpreter config into the new interpreter */
    const PyConfig *src_config;
    if (save_tstate != NULL) {
        src_config = _PyInterpreterState_GetConfig(save_tstate->interp);
    }
    else
    {
        /* No current thread state, copy from the main interpreter */
        PyInterpreterState *main_interp = _PyInterpreterState_Main();
        src_config = _PyInterpreterState_GetConfig(main_interp);
    }

    /* This does not require that the GIL be held. */
    status = _PyConfig_Copy(&interp->config, src_config);
    if (_PyStatus_EXCEPTION(status)) {
        goto error;
    }

    /* This does not require that the GIL be held. */
    status = init_interp_settings(interp, config);
    if (_PyStatus_EXCEPTION(status)) {
        goto error;
    }

    // This could be done in init_interpreter() (in pystate.c) if it
    // didn't depend on interp->feature_flags being set already.
    status = _PyObject_InitState(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

#ifdef Py_STATS
    // initialize pystats.  This must be done after the settings are loaded.
    status = _PyStats_InterpInit(interp);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }
#endif

    // 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;
    }

    tstate = _PyThreadState_New(interp, _PyThreadState_WHENCE_INIT);
    if (tstate == NULL) {
        status = _PyStatus_NO_MEMORY();
        goto error;
    }

    _PyThreadState_Bind(tstate);
    init_interp_create_gil(tstate, config->gil);

    /* No objects have been created yet. */

    status = pycore_interp_init(tstate);
    if (_PyStatus_EXCEPTION(status)) {
        goto error;
    }

    status = init_interp_main(tstate);
    if (_PyStatus_EXCEPTION(status)) {
        goto error;
    }

    *tstate_p = tstate;
    return _PyStatus_OK();

error:
    *tstate_p = NULL;
    if (tstate != NULL) {
        Py_EndInterpreter(tstate);
    } else if (interp != NULL) {
        PyInterpreterState_Delete(interp);
    }
    if (save_tstate != NULL) {
        _PyThreadState_Attach(save_tstate);
    }
    return status;
}

PyStatus
Py_NewInterpreterFromConfig(PyThreadState **tstate_p,
                            const PyInterpreterConfig *config)
{
    long whence = _PyInterpreterState_WHENCE_CAPI;
    return new_interpreter(tstate_p, config, whence);
}

PyThreadState *
Py_NewInterpreter(void)
{
    PyThreadState *tstate = NULL;
    long whence = _PyInterpreterState_WHENCE_LEGACY_CAPI;
    const PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT;
    PyStatus status = new_interpreter(&tstate, &config, whence);
    if (_PyStatus_EXCEPTION(status)) {
        Py_ExitStatusException(status);
    }
    return tstate;
}

/* Delete an interpreter.  This requires that the given thread state
   is current, and that the thread has no remaining frames.
   It is a fatal error to violate these constraints.

   (Py_FinalizeEx() doesn't have these constraints -- it zaps
   everything, regardless.)

   Locking: as above.

*/

void
Py_EndInterpreter(PyThreadState *tstate)
{
    PyInterpreterState *interp = tstate->interp;

    if (tstate != _PyThreadState_GET()) {
        Py_FatalError("thread is not current");
    }
    if (tstate->current_frame != tstate->base_frame) {
        Py_FatalError("thread still has a frame");
    }
    interp->finalizing = 1;

    // This call stops the world and takes the pending calls lock.
    make_pre_finalization_calls(tstate, /*subinterpreters=*/0);

    ASSERT_WORLD_STOPPED(interp);
    /* Remaining daemon threads will automatically exit
       when they attempt to take the GIL (ex: PyEval_RestoreThread()). */
    _PyInterpreterState_SetFinalizing(interp, tstate);

    PyThreadState *list = _PyThreadState_RemoveExcept(tstate);
    for (PyThreadState *p = list; p != NULL; p = p->next) {
        _PyThreadState_SetShuttingDown(p);
    }

    _PyEval_StartTheWorldAll(interp->runtime);
    PyMutex_Unlock(&interp->ceval.pending.mutex);
    _PyThreadState_DeleteList(list, /*is_after_fork=*/0);

    // XXX Call something like _PyImport_Disable() here?

    _PyImport_FiniExternal(tstate->interp);
    finalize_modules(tstate);
    _PyImport_FiniCore(tstate->interp);

    finalize_interp_clear(tstate);
    finalize_interp_delete(tstate->interp);
}

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;
}

static void
finalize_subinterpreters(void)
{
    PyThreadState *final_tstate = _PyThreadState_GET();
    PyInterpreterState *main_interp = _PyInterpreterState_Main();
    assert(final_tstate->interp == main_interp);
    _PyRuntimeState *runtime = main_interp->runtime;
    assert(!runtime->stoptheworld.world_stopped);
    assert(_PyRuntimeState_GetFinalizing(runtime) == NULL);
    struct pyinterpreters *interpreters = &runtime->interpreters;

    /* Get the first interpreter in the list. */
    HEAD_LOCK(runtime);
    PyInterpreterState *interp = interpreters->head;
    if (interp == main_interp) {
        interp = interp->next;
    }
    HEAD_UNLOCK(runtime);

    /* Bail out if there are no subinterpreters left. */
    if (interp == NULL) {
        return;
    }

    /* Warn the user if they forgot to clean up subinterpreters. */
    (void)PyErr_WarnEx(
            PyExc_RuntimeWarning,
            "remaining subinterpreters; "
            "close them with Interpreter.close()",
            0);

    /* Swap out the current tstate, which we know must belong
       to the main interpreter. */
    _PyThreadState_Detach(final_tstate);

    /* Clean up all remaining subinterpreters. */
    while (interp != NULL) {
        /* Make a tstate for finalization. */
        PyThreadState *tstate = _PyThreadState_NewBound(interp, _PyThreadState_WHENCE_FINI);
        if (tstate == NULL) {
            // XXX Some graceful way to always get a thread state?
            Py_FatalError("thread state allocation failed");
        }

        /* Enter the subinterpreter. */
        _PyThreadState_Attach(tstate);

        /* Destroy the subinterpreter. */
        Py_EndInterpreter(tstate);
        assert(_PyThreadState_GET() == NULL);

        /* Advance to the next interpreter. */
        HEAD_LOCK(runtime);
        interp = interpreters->head;
        if (interp == main_interp) {
            interp = interp->next;
        }
        HEAD_UNLOCK(runtime);
    }

    /* Switch back to the main interpreter. */
    _PyThreadState_Attach(final_tstate);
}


/* Add the __main__ module */

static PyStatus
add_main_module(PyInterpreterState *interp)
{
    PyObject *m, *d;
    m = PyImport_AddModuleObject(&_Py_ID(__main__));
    if (m == NULL)
        return _PyStatus_ERR("can't create __main__ module");

    d = PyModule_GetDict(m);

    int has_builtins = PyDict_ContainsString(d, "__builtins__");
    if (has_builtins < 0) {
        return _PyStatus_ERR("Failed to test __main__.__builtins__");
    }
    if (!has_builtins) {
        PyObject *bimod = PyImport_ImportModule("builtins");
        if (bimod == NULL) {
            return _PyStatus_ERR("Failed to retrieve builtins module");
        }
        if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) {
            return _PyStatus_ERR("Failed to initialize __main__.__builtins__");
        }
        Py_DECREF(bimod);
    }

    /* 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
     * process.
     */
    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) {
        PyObject *loader = _PyImport_GetImportlibLoader(interp,
                                                        "BuiltinImporter");
        if (loader == NULL) {
            return _PyStatus_ERR("Failed to retrieve BuiltinImporter");
        }
        if (PyDict_SetItemString(d, "__loader__", loader) < 0) {
            return _PyStatus_ERR("Failed to initialize __main__.__loader__");
        }
        Py_DECREF(loader);
    }
    return _PyStatus_OK();
}

/* Import the site module (not into __main__ though) */

static PyStatus
init_import_site(void)
{
    PyObject *m;
    m = PyImport_ImportModule("site");
    if (m == NULL) {
        return _PyStatus_ERR("Failed to import the site module");
    }
    Py_DECREF(m);
    return _PyStatus_OK();
}

/* returns Py_None if the fd is not valid */
static PyObject*
create_stdio(const PyConfig *config, PyObject* io,
    int fd, int write_mode, const char* name,
    const wchar_t* encoding, const wchar_t* errors)
{
    PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res;
    const char* mode;
    const char* newline;
    PyObject *line_buffering, *write_through;
    int buffering, isatty;
    const int buffered_stdio = config->buffered_stdio;

    if (!_Py_IsValidFD(fd)) {
        Py_RETURN_NONE;
    }

    /* 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.
    */
    if (!buffered_stdio && write_mode)
        buffering = 0;
    else
        buffering = -1;
    if (write_mode)
        mode = "wb";
    else
        mode = "rb";
    buf = _PyObject_CallMethod(io, &_Py_ID(open), "isiOOOO",
                               fd, mode, buffering,
                               Py_None, Py_None, /* encoding, errors */
                               Py_None, Py_False); /* newline, closefd */
    if (buf == NULL)
        goto error;

    if (buffering) {
        raw = PyObject_GetAttr(buf, &_Py_ID(raw));
        if (raw == NULL)
            goto error;
    }
    else {
        raw = Py_NewRef(buf);
    }

#ifdef HAVE_WINDOWS_CONSOLE_IO
    /* Windows console IO is always UTF-8 encoded */
    PyTypeObject *winconsoleio_type = (PyTypeObject *)PyImport_ImportModuleAttr(
            &_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) {
        encoding = L"utf-8";
    }
#endif

    text = PyUnicode_FromString(name);
    if (text == NULL || PyObject_SetAttr(raw, &_Py_ID(name), text) < 0)
        goto error;
    res = PyObject_CallMethodNoArgs(raw, &_Py_ID(isatty));
    if (res == NULL)
        goto error;
    isatty = PyObject_IsTrue(res);
    Py_DECREF(res);
    if (isatty == -1)
        goto error;
    if (!buffered_stdio)
        write_through = Py_True;
    else
        write_through = Py_False;
    if (buffered_stdio && (isatty || fd == fileno(stderr)))
        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

    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;
    }

    stream = _PyObject_CallMethod(io, &_Py_ID(TextIOWrapper), "OOOsOO",
                                  buf, encoding_str, errors_str,
                                  newline, line_buffering, write_through);
    Py_CLEAR(buf);
    Py_CLEAR(encoding_str);
    Py_CLEAR(errors_str);
    if (stream == NULL)
        goto error;

    if (write_mode)
        mode = "w";
    else
        mode = "r";
    text = PyUnicode_FromString(mode);
    if (!text || PyObject_SetAttr(stream, &_Py_ID(mode), text) < 0)
        goto error;
    Py_CLEAR(text);
    return stream;

error:
    Py_XDECREF(buf);
    Py_XDECREF(stream);
    Py_XDECREF(text);
    Py_XDECREF(raw);

    if (PyErr_ExceptionMatches(PyExc_OSError) && !_Py_IsValidFD(fd)) {
        /* Issue #24891: the file descriptor was closed after the first
           _Py_IsValidFD() check was called. Ignore the OSError and set the
           stream to None. */
        PyErr_Clear();
        Py_RETURN_NONE;
    }
    return NULL;
}

/* Set builtins.open to io.open */
static PyStatus
init_set_builtins_open(void)
{
    PyObject *wrapper;
    PyObject *bimod = NULL;
    PyStatus res = _PyStatus_OK();

    if (!(bimod = PyImport_ImportModule("builtins"))) {
        goto error;
    }

    if (!(wrapper = PyImport_ImportModuleAttrString("_io", "open"))) {
        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;
}


/* Create sys.stdin, sys.stdout and sys.stderr */
static PyStatus
init_sys_streams(PyThreadState *tstate)
{
    PyObject *iomod = NULL;
    PyObject *std = NULL;
    int fd;
    PyObject * encoding_attr;
    PyStatus res = _PyStatus_OK();
    const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);

    /* 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)) {
        return _PyStatus_ERR("<stdin> is a directory, cannot continue");
    }
#endif

    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.
     */
    std = create_stdio(config, iomod, fd, 0, "<stdin>",
                       config->stdio_encoding,
                       config->stdio_errors);
    if (std == NULL)
        goto error;
    PySys_SetObject("__stdin__", std);
    _PySys_SetAttr(&_Py_ID(stdin), std);
    Py_DECREF(std);

    /* Set sys.stdout */
    fd = fileno(stdout);
    std = create_stdio(config, iomod, fd, 1, "<stdout>",
                       config->stdio_encoding,
                       config->stdio_errors);
    if (std == NULL)
        goto error;
    PySys_SetObject("__stdout__", std);
    _PySys_SetAttr(&_Py_ID(stdout), std);
    Py_DECREF(std);

#if 1 /* Disable this if you have trouble debugging bootstrap stuff */
    /* Set sys.stderr, replaces the preliminary stderr */
    fd = fileno(stderr);
    std = create_stdio(config, iomod, fd, 1, "<stderr>",
                       config->stdio_encoding,
                       L"backslashreplace");
    if (std == NULL)
        goto error;

    /* 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) {
        const char *std_encoding = PyUnicode_AsUTF8(encoding_attr);
        if (std_encoding != NULL) {
            PyObject *codec_info = _PyCodec_Lookup(std_encoding);
            Py_XDECREF(codec_info);
        }
        Py_DECREF(encoding_attr);
    }
    _PyErr_Clear(tstate);  /* Not a fatal error if codec isn't available */

    if (PySys_SetObject("__stderr__", std) < 0) {
        Py_DECREF(std);
        goto error;
    }
    if (_PySys_SetAttr(&_Py_ID(stderr), std) < 0) {
        Py_DECREF(std);
        goto error;
    }
    Py_DECREF(std);
#endif

    goto done;

error:
    res = _PyStatus_ERR("can't initialize sys standard streams");

done:
    Py_XDECREF(iomod);
    return res;
}


#ifdef __ANDROID__
#include <android/log.h>

static PyObject *
android_log_write_impl(PyObject *self, PyObject *args)
{
    int prio = 0;
    const char *tag = NULL;
    const char *text = NULL;
    if (!PyArg_ParseTuple(args, "isy", &prio, &tag, &text)) {
        return NULL;
    }

    // Despite its name, this function is part of the public API
    // (https://developer.android.com/ndk/reference/group/logging).
    __android_log_write(prio, tag, text);
    Py_RETURN_NONE;
}


static PyMethodDef android_log_write_method = {
    "android_log_write", android_log_write_impl, METH_VARARGS
};


static PyStatus
init_android_streams(PyThreadState *tstate)
{
    PyStatus status = _PyStatus_OK();
    PyObject *_android_support = NULL;
    PyObject *android_log_write = NULL;
    PyObject *result = NULL;

    _android_support = PyImport_ImportModule("_android_support");
    if (_android_support == NULL) {
        goto error;
    }

    android_log_write = PyCFunction_New(&android_log_write_method, NULL);
    if (android_log_write == NULL) {
        goto error;
    }

    // These log priorities match those used by Java's System.out and System.err.
    result = PyObject_CallMethod(
        _android_support, "init_streams", "Oii",
        android_log_write, ANDROID_LOG_INFO, ANDROID_LOG_WARN);
    if (result == NULL) {
        goto error;
    }

    goto done;

error:
    _PyErr_Print(tstate);
    status = _PyStatus_ERR("failed to initialize Android streams");

done:
    Py_XDECREF(result);
    Py_XDECREF(android_log_write);
    Py_XDECREF(_android_support);
    return status;
}

#endif  // __ANDROID__

#if defined(__APPLE__) && HAS_APPLE_SYSTEM_LOG

static PyObject *
apple_log_write_impl(PyObject *self, PyObject *args)
{
    int logtype = 0;
    const char *text = NULL;
    if (!PyArg_ParseTuple(args, "iy", &logtype, &text)) {
        return NULL;
    }

    // Pass the user-provided text through explicit %s formatting
    // to avoid % literals being interpreted as a formatting directive.
    os_log_with_type(OS_LOG_DEFAULT, logtype, "%s", text);
    Py_RETURN_NONE;
}


static PyMethodDef apple_log_write_method = {
    "apple_log_write", apple_log_write_impl, METH_VARARGS
};


static PyStatus
init_apple_streams(PyThreadState *tstate)
{
    PyStatus status = _PyStatus_OK();
    PyObject *_apple_support = NULL;
    PyObject *apple_log_write = NULL;
    PyObject *result = NULL;

    _apple_support = PyImport_ImportModule("_apple_support");
    if (_apple_support == NULL) {
        goto error;
    }

    apple_log_write = PyCFunction_New(&apple_log_write_method, NULL);
    if (apple_log_write == NULL) {
        goto error;
    }

    // Initialize the logging streams, sending stdout -> Default; stderr -> Error
    result = PyObject_CallMethod(
        _apple_support, "init_streams", "Oii",
        apple_log_write, OS_LOG_TYPE_DEFAULT, OS_LOG_TYPE_ERROR);
    if (result == NULL) {
        goto error;
    }
    goto done;

error:
    _PyErr_Print(tstate);
    status = _PyStatus_ERR("failed to initialize Apple log streams");

done:
    Py_XDECREF(result);
    Py_XDECREF(apple_log_write);
    Py_XDECREF(_apple_support);
    return status;
}

#endif  // __APPLE__ && HAS_APPLE_SYSTEM_LOG


static void
_Py_FatalError_DumpTracebacks(int fd, PyInterpreterState *interp,
                              PyThreadState *tstate)
{
    PUTS(fd, "\n");

    /* display the current Python stack */
#ifndef Py_GIL_DISABLED
    PyUnstable_DumpTracebackThreads(fd, interp, tstate, 0);
#else
    PyUnstable_DumpTraceback(fd, tstate);
#endif
}

/* Print the current exception (if an exception is set) with its traceback,
   or display the current Python stack.

   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
_Py_FatalError_PrintExc(PyThreadState *tstate)
{
    PyObject *exc = _PyErr_GetRaisedException(tstate);
    if (exc == NULL) {
        /* No current exception */
        return 0;
    }

    PyObject *ferr;
    if (PySys_GetOptionalAttr(&_Py_ID(stderr), &ferr) < 0) {
        _PyErr_Clear(tstate);
    }
    if (ferr == NULL || ferr == Py_None) {
        /* sys.stderr is not set yet or set to None,
           no need to try to display the exception */
        Py_XDECREF(ferr);
        Py_DECREF(exc);
        return 0;
    }

    PyErr_DisplayException(exc);

    PyObject *tb = PyException_GetTraceback(exc);
    int has_tb = (tb != NULL) && (tb != Py_None);
    Py_XDECREF(tb);
    Py_DECREF(exc);

    /* sys.stderr may be buffered: call sys.stderr.flush() */
    if (_PyFile_Flush(ferr) < 0) {
        _PyErr_Clear(tstate);
    }
    Py_DECREF(ferr);

    return has_tb;
}

/* Print fatal error message and abort */

#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


static void
fatal_error_dump_runtime(int fd, _PyRuntimeState *runtime)
{
    PUTS(fd, "Python runtime state: ");
    PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime);
    if (finalizing) {
        PUTS(fd, "finalizing (tstate=0x");
        _Py_DumpHexadecimal(fd, (uintptr_t)finalizing, sizeof(finalizing) * 2);
        PUTS(fd, ")");
    }
    else if (_PyRuntimeState_GetInitialized(runtime)) {
        PUTS(fd, "initialized");
    }
    else if (_PyRuntimeState_GetCoreInitialized(runtime)) {
        PUTS(fd, "core initialized");
    }
    else if (runtime->preinitialized) {
        PUTS(fd, "preinitialized");
    }
    else if (runtime->preinitializing) {
        PUTS(fd, "preinitializing");
    }
    else {
        PUTS(fd, "unknown");
    }
    PUTS(fd, "\n");
}


static inline void _Py_NO_RETURN
fatal_error_exit(int status)
{
    if (status < 0) {
#if defined(MS_WINDOWS) && defined(Py_DEBUG)
        DebugBreak();
#endif
        abort();
    }
    else {
        exit(status);
    }
}

static inline int
acquire_dict_lock_for_dump(PyObject *obj)
{
#ifdef Py_GIL_DISABLED
    PyMutex *mutex = &obj->ob_mutex;
    if (_PyMutex_LockTimed(mutex, 0, 0) == PY_LOCK_ACQUIRED) {
        return 1;
    }
    return 0;
#else
    return 1;
#endif
}

static inline void
release_dict_lock_for_dump(PyObject *obj)
{
#ifdef Py_GIL_DISABLED
    PyMutex *mutex = &obj->ob_mutex;
    // We can not call PyMutex_Unlock because it's not async-signal-safe.
    // So not to wake up other threads, we just use a simple atomic store in here.
    _Py_atomic_store_uint8(&mutex->_bits, _Py_UNLOCKED);
#endif
}

// Dump the list of extension modules of sys.modules, excluding stdlib modules
// (sys.stdlib_module_names), into fd file descriptor.
//
// This function is called by a signal handler in faulthandler: avoid memory
// allocations and keep the implementation simple. For example, the list is not
// sorted on purpose.
void
_Py_DumpExtensionModules(int fd, PyInterpreterState *interp)
{
    if (interp == NULL) {
        return;
    }
    PyObject *modules = _PyImport_GetModules(interp);
    if (modules == NULL || !PyDict_Check(modules)) {
        return;
    }

    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.
    PyObject *stdlib_module_names = NULL;
    if (interp->sysdict != NULL) {
        pos = 0;
        if (!acquire_dict_lock_for_dump(interp->sysdict)) {
            // If we cannot acquire the lock, just don't dump the list of extension modules.
            return;
        }
        while (_PyDict_Next(interp->sysdict, &pos, &key, &value, NULL)) {
            if (PyUnicode_Check(key)
               && PyUnicode_CompareWithASCIIString(key, "stdlib_module_names") == 0) {
                stdlib_module_names = value;
                break;
            }
        }
        release_dict_lock_for_dump(interp->sysdict);
    }
    // If we failed to get sys.stdlib_module_names or it's not a frozenset,
    // don't exclude stdlib modules.
    if (stdlib_module_names != NULL && !PyFrozenSet_Check(stdlib_module_names)) {
        stdlib_module_names = NULL;
    }

    // List extensions
    int header = 1;
    Py_ssize_t count = 0;
    pos = 0;
    if (!acquire_dict_lock_for_dump(modules)) {
        // If we cannot acquire the lock, just don't dump the list of extension modules.
        return;
    }
    while (_PyDict_Next(modules, &pos, &key, &value, NULL)) {
        if (!PyUnicode_Check(key)) {
            continue;
        }
        if (!_PyModule_IsExtension(value)) {
            continue;
        }
        // Use the module name from the sys.modules key,
        // don't attempt to get the module object name.
        if (stdlib_module_names != NULL) {
            int is_stdlib_ext = 0;

            Py_ssize_t i = 0;
            PyObject *item;
            Py_hash_t hash;
            // if stdlib_module_names is not NULL, it is always a frozenset.
            while (_PySet_NextEntry(stdlib_module_names, &i, &item, &hash)) {
                if (!PyUnicode_Check(item)) {
                    continue;
                }
                Py_ssize_t len = PyUnicode_GET_LENGTH(item);
                if (PyUnicode_Tailmatch(key, item, 0, len, -1) == 1) {
                    Py_ssize_t key_len = PyUnicode_GET_LENGTH(key);
                    if (key_len == len) {
                        is_stdlib_ext = 1;
                        break;
                    }
                    assert(key_len > len);

                    // Ignore sub-modules of stdlib packages. For example,
                    // ignore "math.integer" if key starts with "math.".
                    Py_UCS4 ch = PyUnicode_ReadChar(key, len);
                    if (ch == '.') {
                        is_stdlib_ext = 1;
                        break;
                    }
                }
            }
            if (is_stdlib_ext) {
                // Ignore stdlib extension
                continue;
            }
        }

        if (header) {
            PUTS(fd, "\nExtension modules: ");
            header = 0;
        }
        else {
            PUTS(fd, ", ");
        }

        _Py_DumpASCII(fd, key);
        count++;
    }
    release_dict_lock_for_dump(modules);

    if (count) {
        PUTS(fd, " (total: ");
        _Py_DumpDecimal(fd, count);
        PUTS(fd, ")");
        PUTS(fd, "\n");
    }
}


static void _Py_NO_RETURN
fatal_error(int fd, int header, const char *prefix, const char *msg,
            int status)
{
    static int reentrant = 0;

    if (reentrant) {
        /* Py_FatalError() caused a second fatal error.
           Example: flush_std_files() raises a recursion error. */
        fatal_error_exit(status);
    }
    reentrant = 1;

    if (header) {
        PUTS(fd, "Fatal Python error: ");
        if (prefix) {
            PUTS(fd, prefix);
            PUTS(fd, ": ");
        }
        if (msg) {
            PUTS(fd, msg);
        }
        else {
            PUTS(fd, "<message not set>");
        }
        PUTS(fd, "\n");
    }

    _PyRuntimeState *runtime = &_PyRuntime;
    fatal_error_dump_runtime(fd, runtime);

    /* 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.
       */
    PyThreadState *tstate = _PyThreadState_GET();
    PyInterpreterState *interp = NULL;
    PyThreadState *tss_tstate = PyGILState_GetThisThreadState();
    if (tstate != NULL) {
        interp = tstate->interp;
    }
    else if (tss_tstate != NULL) {
        interp = tss_tstate->interp;
    }
    int has_tstate_and_gil = (tss_tstate != NULL && tss_tstate == tstate);

    if (has_tstate_and_gil) {
        /* If an exception is set, print the exception with its traceback */
        if (!_Py_FatalError_PrintExc(tss_tstate)) {
            /* No exception is set, or an exception is set without traceback */
            _Py_FatalError_DumpTracebacks(fd, interp, tss_tstate);
        }
    }
    else {
        _Py_FatalError_DumpTracebacks(fd, interp, tss_tstate);
    }

    _Py_DumpExtensionModules(fd, interp);

    /* 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(). */
    _PyFaulthandler_Fini();

    /* Check if the current Python thread hold the GIL */
    if (has_tstate_and_gil) {
        /* Flush sys.stdout and sys.stderr */
        flush_std_files();
    }

#ifdef MS_WINDOWS
    fatal_output_debug(msg);
#endif /* MS_WINDOWS */

    fatal_error_exit(status);
}


#undef Py_FatalError

void _Py_NO_RETURN
Py_FatalError(const char *msg)
{
    fatal_error(fileno(stderr), 1, NULL, msg, -1);
}


void _Py_NO_RETURN
_Py_FatalErrorFunc(const char *func, const char *msg)
{
    fatal_error(fileno(stderr), 1, func, msg, -1);
}


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;
    const int fd = fileno(stream);
    PUTS(fd, "Fatal Python error: ");
    if (func) {
        PUTS(fd, func);
        PUTS(fd, ": ");
    }

    va_list vargs;
    va_start(vargs, format);
    vfprintf(stream, format, vargs);
    va_end(vargs);

    fputs("\n", stream);
    fflush(stream);

    fatal_error(fd, 0, NULL, NULL, -1);
}


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);
}


void _Py_NO_RETURN
Py_ExitStatusException(PyStatus status)
{
    if (_PyStatus_IS_EXIT(status)) {
        exit(status.exitcode);
    }
    else if (_PyStatus_IS_ERROR(status)) {
        fatal_error(fileno(stderr), 1, status.func, status.err_msg, 1);
    }
    else {
        Py_FatalError("Py_ExitStatusException() must not be called on success");
    }
}


static void
handle_thread_shutdown_exception(PyThreadState *tstate)
{
    assert(tstate != NULL);
    assert(_PyErr_Occurred(tstate));
    PyInterpreterState *interp = tstate->interp;
    assert(interp->threads.head != NULL);
    _PyEval_StopTheWorld(interp);

    // We don't have to worry about locking this because the
    // world is stopped.
    _Py_FOR_EACH_TSTATE_UNLOCKED(interp, tstate) {
        if (tstate->_whence == _PyThreadState_WHENCE_THREADING) {
            tstate->_whence = _PyThreadState_WHENCE_THREADING_DAEMON;
        }
    }

    _PyEval_StartTheWorld(interp);
    PyErr_FormatUnraisable("Exception ignored on threading shutdown");
}

/* 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
wait_for_thread_shutdown(PyThreadState *tstate)
{
    PyObject *result;
    PyObject *threading = PyImport_GetModule(&_Py_ID(threading));
    if (threading == NULL) {
        if (_PyErr_Occurred(tstate)) {
            handle_thread_shutdown_exception(tstate);
        }
        /* else: threading not imported */
        return;
    }
    result = PyObject_CallMethodNoArgs(threading, &_Py_ID(_shutdown));
    if (result == NULL) {
        handle_thread_shutdown_exception(tstate);
    }
    else {
        Py_DECREF(result);
    }
    Py_DECREF(threading);
}

int Py_AtExit(void (*func)(void))
{
    struct _atexit_runtime_state *state = &_PyRuntime.atexit;
    PyMutex_Lock(&state->mutex);
    if (state->ncallbacks >= NEXITFUNCS) {
        PyMutex_Unlock(&state->mutex);
        return -1;
    }
    state->callbacks[state->ncallbacks++] = func;
    PyMutex_Unlock(&state->mutex);
    return 0;
}

static void
call_ll_exitfuncs(_PyRuntimeState *runtime)
{
    atexit_callbackfunc exitfunc;
    struct _atexit_runtime_state *state = &runtime->atexit;

    PyMutex_Lock(&state->mutex);
    while (state->ncallbacks > 0) {
        /* pop last function from the list */
        state->ncallbacks--;
        exitfunc = state->callbacks[state->ncallbacks];
        state->callbacks[state->ncallbacks] = NULL;

        PyMutex_Unlock(&state->mutex);
        exitfunc();
        PyMutex_Lock(&state->mutex);
    }
    PyMutex_Unlock(&state->mutex);

    fflush(stdout);
    fflush(stderr);
}

void _Py_NO_RETURN
Py_Exit(int sts)
{
    PyThreadState *tstate = _PyThreadState_GET();
    if (tstate != NULL && _PyThreadState_IsRunningMain(tstate)) {
        _PyInterpreterState_SetNotRunningMain(tstate->interp);
    }
    if (_Py_Finalize(&_PyRuntime) < 0) {
        sts = 120;
    }

    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)
{
    if (isatty(fileno(fp))) {
        return 1;
    }
    if (!_Py_GetConfig()->interactive) {
        return 0;
    }
    return ((filename == NULL)
            || (strcmp(filename, "<stdin>") == 0)
            || (strcmp(filename, "???") == 0));
}


int
_Py_FdIsInteractive(FILE *fp, PyObject *filename)
{
    if (isatty(fileno(fp))) {
        return 1;
    }
    if (!_Py_GetConfig()->interactive) {
        return 0;
    }
    return ((filename == NULL)
            || (PyUnicode_CompareWithASCIIString(filename, "<stdin>") == 0)
            || (PyUnicode_CompareWithASCIIString(filename, "???") == 0));
}


/* 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-safety` 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);
    /* 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;
    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
}
