/* Module definition and import implementation */

#include "Python.h"
#include "pycore_audit.h"         // _PySys_Audit()
#include "pycore_ceval.h"
#include "pycore_critical_section.h"  // Py_BEGIN_CRITICAL_SECTION()
#include "pycore_dict.h"          // _PyDict_Contains_KnownHash()
#include "pycore_hashtable.h"     // _Py_hashtable_new_full()
#include "pycore_import.h"        // _PyImport_BootstrapImp()
#include "pycore_initconfig.h"    // _PyStatus_OK()
#include "pycore_interp.h"        // struct _import_runtime_state
#include "pycore_interpframe.h"
#include "pycore_lazyimportobject.h"
#include "pycore_long.h"          // _PyLong_GetZero
#include "pycore_magic_number.h"  // PYC_MAGIC_NUMBER_TOKEN
#include "pycore_moduleobject.h"  // _PyModule_GetDef()
#include "pycore_namespace.h"     // _PyNamespace_Type
#include "pycore_object.h"        // _Py_SetImmortal()
#include "pycore_pyatomic_ft_wrappers.h"
#include "pycore_pyerrors.h"      // _PyErr_SetString()
#include "pycore_pyhash.h"        // _Py_KeyedHash()
#include "pycore_pylifecycle.h"
#include "pycore_pymem.h"         // _PyMem_DefaultRawFree()
#include "pycore_pystate.h"       // _PyInterpreterState_GET()
#include "pycore_setobject.h"     // _PySet_NextEntry()
#include "pycore_sysmodule.h"     // _PySys_ClearAttrString()
#include "pycore_time.h"          // _PyTime_AsMicroseconds()
#include "pycore_traceback.h"
#include "pycore_unicodeobject.h" // _PyUnicode_AsUTF8NoNUL()
#include "pycore_weakref.h"       // _PyWeakref_GET_REF()

#include "marshal.h"              // PyMarshal_ReadObjectFromString()
#include "pycore_importdl.h"      // _PyImport_DynLoadFiletab
#include "pydtrace.h"             // PyDTrace_IMPORT_FIND_LOAD_START_ENABLED()
#include <stdbool.h>              // bool

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


/*[clinic input]
module _imp
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9c332475d8686284]*/

#include "clinic/import.c.h"


#ifndef NDEBUG
static bool
is_interpreter_isolated(PyInterpreterState *interp)
{
    return !_Py_IsMainInterpreter(interp)
        && !(interp->feature_flags & Py_RTFLAGS_USE_MAIN_OBMALLOC)
        && interp->ceval.own_gil;
}
#endif


/*******************************/
/* process-global import state */
/*******************************/

/* This table is defined in config.c: */
extern struct _inittab _PyImport_Inittab[];

// This is not used after Py_Initialize() is called.
// (See _PyRuntimeState.imports.inittab.)
struct _inittab *PyImport_Inittab = _PyImport_Inittab;
// When we dynamically allocate a larger table for PyImport_ExtendInittab(),
// we track the pointer here so we can deallocate it during finalization.
static struct _inittab *inittab_copy = NULL;


/*******************************/
/* runtime-global import state */
/*******************************/

#define INITTAB _PyRuntime.imports.inittab
#define LAST_MODULE_INDEX _PyRuntime.imports.last_module_index
#define EXTENSIONS _PyRuntime.imports.extensions


/*******************************/
/* interpreter import state */
/*******************************/

#define MODULES(interp) \
    (interp)->imports.modules
#define MODULES_BY_INDEX(interp) \
    (interp)->imports.modules_by_index
#define LAZY_MODULES(interp) \
    (interp)->imports.lazy_modules
#define LAZY_PENDING_SUBMODULES(interp) \
    (interp)->imports.lazy_pending_submodules
#define IMPORTLIB(interp) \
    (interp)->imports.importlib
#define OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK(interp) \
    (interp)->imports.override_multi_interp_extensions_check
#define OVERRIDE_FROZEN_MODULES(interp) \
    (interp)->imports.override_frozen_modules
#ifdef HAVE_DLOPEN
#  define DLOPENFLAGS(interp) \
        (interp)->imports.dlopenflags
#endif
#define IMPORT_FUNC(interp) \
    (interp)->imports.import_func

#define LAZY_IMPORT_FUNC(interp) \
    (interp)->imports.lazy_import_func

#define IMPORT_LOCK(interp) \
    (interp)->imports.lock

#define FIND_AND_LOAD(interp) \
    (interp)->imports.find_and_load

#define LAZY_IMPORTS_MODE(interp) \
    (interp)->imports.lazy_imports_mode

#define LAZY_IMPORTS_FILTER(interp) \
    (interp)->imports.lazy_imports_filter

#ifdef Py_GIL_DISABLED
#define LAZY_IMPORTS_LOCK(interp) PyMutex_Lock(&(interp)->imports.lazy_mutex)
#define LAZY_IMPORTS_UNLOCK(interp) PyMutex_Unlock(&(interp)->imports.lazy_mutex)
#else
#define LAZY_IMPORTS_LOCK(interp)
#define LAZY_IMPORTS_UNLOCK(interp)
#endif


#define _IMPORT_TIME_HEADER(interp)                                           \
    do {                                                                      \
        if (FIND_AND_LOAD((interp)).header) {                                 \
            fputs("import time: self [us] | cumulative | imported package\n", \
                  stderr);                                                    \
            FIND_AND_LOAD((interp)).header = 0;                               \
        }                                                                     \
    } while (0)


/*******************/
/* the import lock */
/*******************/

/* Locking primitives to prevent parallel imports of the same module
   in different threads to return with a partially loaded module.
   These calls are serialized by the global interpreter lock. */

void
_PyImport_AcquireLock(PyInterpreterState *interp)
{
    _PyRecursiveMutex_Lock(&IMPORT_LOCK(interp));
}

void
_PyImport_ReleaseLock(PyInterpreterState *interp)
{
    _PyRecursiveMutex_Unlock(&IMPORT_LOCK(interp));
}

void
_PyImport_ReInitLock(PyInterpreterState *interp)
{
    // gh-126688: Thread id may change after fork() on some operating systems.
    IMPORT_LOCK(interp).thread = PyThread_get_thread_ident_ex();
}


/***************/
/* sys.modules */
/***************/

PyObject *
_PyImport_InitModules(PyInterpreterState *interp)
{
    assert(MODULES(interp) == NULL);
    MODULES(interp) = PyDict_New();
    if (MODULES(interp) == NULL) {
        return NULL;
    }
    return MODULES(interp);
}

PyObject *
_PyImport_GetModules(PyInterpreterState *interp)
{
    return MODULES(interp);
}

PyObject *
_PyImport_GetModulesRef(PyInterpreterState *interp)
{
    _PyImport_AcquireLock(interp);
    PyObject *modules = MODULES(interp);
    if (modules == NULL) {
        /* The interpreter hasn't been initialized yet. */
        modules = Py_None;
    }
    Py_INCREF(modules);
    _PyImport_ReleaseLock(interp);
    return modules;
}

void
_PyImport_ClearModules(PyInterpreterState *interp)
{
    Py_SETREF(MODULES(interp), NULL);
}

static inline PyObject *
get_modules_dict(PyThreadState *tstate, bool fatal)
{
    /* Technically, it would make sense to incref the dict,
     * since sys.modules could be swapped out and decref'ed to 0
     * before the caller is done using it.  However, that is highly
     * unlikely, especially since we can rely on a global lock
     * (i.e. the GIL) for thread-safety. */
    PyObject *modules = MODULES(tstate->interp);
    if (modules == NULL) {
        if (fatal) {
            Py_FatalError("interpreter has no modules dictionary");
        }
        _PyErr_SetString(tstate, PyExc_RuntimeError,
                         "unable to get sys.modules");
        return NULL;
    }
    return modules;
}

PyObject *
PyImport_GetModuleDict(void)
{
    PyThreadState *tstate = _PyThreadState_GET();
    return get_modules_dict(tstate, true);
}

int
_PyImport_SetModule(PyObject *name, PyObject *m)
{
    PyThreadState *tstate = _PyThreadState_GET();
    PyObject *modules = get_modules_dict(tstate, true);
    return PyObject_SetItem(modules, name, m);
}

int
_PyImport_SetModuleString(const char *name, PyObject *m)
{
    PyThreadState *tstate = _PyThreadState_GET();
    PyObject *modules = get_modules_dict(tstate, true);
    return PyMapping_SetItemString(modules, name, m);
}

static PyObject *
import_get_module(PyThreadState *tstate, PyObject *name)
{
    PyObject *modules = get_modules_dict(tstate, false);
    if (modules == NULL) {
        return NULL;
    }

    PyObject *m;
    Py_INCREF(modules);
    (void)PyMapping_GetOptionalItem(modules, name, &m);
    Py_DECREF(modules);
    return m;
}

PyObject *
_PyImport_InitLazyModules(PyInterpreterState *interp)
{
    assert(LAZY_MODULES(interp) == NULL &&
           LAZY_PENDING_SUBMODULES(interp) == NULL);

    LAZY_PENDING_SUBMODULES(interp) = PyDict_New();
    LAZY_MODULES(interp) = PySet_New(0);
    return LAZY_MODULES(interp);
}

void
_PyImport_ClearLazyModules(PyInterpreterState *interp)
{
    Py_CLEAR(LAZY_MODULES(interp));
    Py_CLEAR(LAZY_PENDING_SUBMODULES(interp));
}

static int
import_ensure_initialized(PyInterpreterState *interp, PyObject *mod, PyObject *name)
{
    PyObject *spec;

    /* Optimization: only call _bootstrap._lock_unlock_module() if
       __spec__._initializing is true.
       NOTE: because of this, initializing must be set *before*
       stuffing the new module in sys.modules.
    */
    int rc = PyObject_GetOptionalAttr(mod, &_Py_ID(__spec__), &spec);
    if (rc > 0) {
        rc = _PyModuleSpec_IsInitializing(spec);
        Py_DECREF(spec);
    }
    if (rc == 0) {
        goto done;
    }
    else if (rc < 0) {
        return rc;
    }

    /* Wait until module is done importing. */
    PyObject *value = PyObject_CallMethodOneArg(
        IMPORTLIB(interp), &_Py_ID(_lock_unlock_module), name);
    if (value == NULL) {
        return -1;
    }
    Py_DECREF(value);

done:
    /* When -X importtime=2, print an import time entry even if an
       imported module has already been loaded.
     */
    if (_PyInterpreterState_GetConfig(interp)->import_time == 2) {
        _IMPORT_TIME_HEADER(interp);
#define import_level FIND_AND_LOAD(interp).import_level
        fprintf(stderr, "import time: cached    | cached     | %*s\n",
                import_level*2, PyUnicode_AsUTF8(name));
#undef import_level
    }

    return 0;
}

static void remove_importlib_frames(PyThreadState *tstate);

PyObject *
PyImport_GetModule(PyObject *name)
{
    PyThreadState *tstate = _PyThreadState_GET();
    PyObject *mod;

    mod = import_get_module(tstate, name);
    if (mod != NULL && mod != Py_None) {
        if (import_ensure_initialized(tstate->interp, mod, name) < 0) {
            goto error;
        }
        /* Verify the module is still in sys.modules. Another thread may have
           removed it (due to import failure) between our import_get_module()
           call and the _initializing check in import_ensure_initialized(). */
        PyObject *mod_check = import_get_module(tstate, name);
        if (mod_check != mod) {
            Py_XDECREF(mod_check);
            if (_PyErr_Occurred(tstate)) {
                goto error;
            }
            /* The module was removed or replaced. Return NULL to report
               "not found" rather than trying to keep up with racing
               modifications to sys.modules; returning the new value would
               require looping to redo the ensure_initialized check. */
            Py_DECREF(mod);
            return NULL;
        }
        Py_DECREF(mod_check);
    }
    return mod;

error:
    Py_DECREF(mod);
    remove_importlib_frames(tstate);
    return NULL;
}

/* Get the module object corresponding to a module name.
   First check the modules dictionary if there's one there,
   if not, create a new one and insert it in the modules dictionary. */

static PyObject *
import_add_module_lock_held(PyObject *modules, PyObject *name)
{
    PyObject *m;
    if (PyMapping_GetOptionalItem(modules, name, &m) < 0) {
        return NULL;
    }
    if (m != NULL && PyModule_Check(m)) {
        return m;
    }
    Py_XDECREF(m);
    m = PyModule_NewObject(name);
    if (m == NULL)
        return NULL;
    if (PyObject_SetItem(modules, name, m) != 0) {
        Py_DECREF(m);
        return NULL;
    }

    return m;
}

static PyObject *
import_add_module(PyThreadState *tstate, PyObject *name)
{
    PyObject *modules = get_modules_dict(tstate, false);
    if (modules == NULL) {
        return NULL;
    }

    PyObject *m;
    Py_BEGIN_CRITICAL_SECTION(modules);
    m = import_add_module_lock_held(modules, name);
    Py_END_CRITICAL_SECTION();
    return m;
}

PyObject *
PyImport_AddModuleRef(const char *name)
{
    PyObject *name_obj = PyUnicode_FromString(name);
    if (name_obj == NULL) {
        return NULL;
    }
    PyThreadState *tstate = _PyThreadState_GET();
    PyObject *module = import_add_module(tstate, name_obj);
    Py_DECREF(name_obj);
    return module;
}


PyObject *
PyImport_AddModuleObject(PyObject *name)
{
    PyThreadState *tstate = _PyThreadState_GET();
    PyObject *mod = import_add_module(tstate, name);
    if (!mod) {
        return NULL;
    }

    // gh-86160: PyImport_AddModuleObject() returns a borrowed reference.
    // Create a weak reference to produce a borrowed reference, since it can
    // become NULL. sys.modules type can be different than dict and it is not
    // guaranteed that it keeps a strong reference to the module. It can be a
    // custom mapping with __getitem__() which returns a new object or removes
    // returned object, or __setitem__ which does nothing. There is so much
    // unknown.  With weakref we can be sure that we get either a reference to
    // live object or NULL.
    //
    // Use PyImport_AddModuleRef() to avoid these issues.
    PyObject *ref = PyWeakref_NewRef(mod, NULL);
    Py_DECREF(mod);
    if (ref == NULL) {
        return NULL;
    }
    mod = _PyWeakref_GET_REF(ref);
    Py_DECREF(ref);
    Py_XDECREF(mod);

    if (mod == NULL && !PyErr_Occurred()) {
        PyErr_SetString(PyExc_RuntimeError,
                        "sys.modules does not hold a strong reference "
                        "to the module");
    }
    return mod; /* borrowed reference */
}


PyObject *
PyImport_AddModule(const char *name)
{
    PyObject *nameobj = PyUnicode_FromString(name);
    if (nameobj == NULL) {
        return NULL;
    }
    PyObject *module = PyImport_AddModuleObject(nameobj);
    Py_DECREF(nameobj);
    return module;
}


/* Remove name from sys.modules, if it's there.
 * Can be called with an exception raised.
 * If fail to remove name a new exception will be chained with the old
 * exception, otherwise the old exception is preserved.
 */
static void
remove_module(PyThreadState *tstate, PyObject *name)
{
    PyObject *exc = _PyErr_GetRaisedException(tstate);

    PyObject *modules = get_modules_dict(tstate, true);
    if (PyDict_CheckExact(modules)) {
        // Error is reported to the caller
        (void)PyDict_Pop(modules, name, NULL);
    }
    else if (PyMapping_DelItem(modules, name) < 0) {
        if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
            _PyErr_Clear(tstate);
        }
    }

    _PyErr_ChainExceptions1(exc);
}


/************************************/
/* per-interpreter modules-by-index */
/************************************/

Py_ssize_t
_PyImport_GetNextModuleIndex(void)
{
    return _Py_atomic_add_ssize(&LAST_MODULE_INDEX, 1) + 1;
}

#ifndef NDEBUG
struct extensions_cache_value;
static struct extensions_cache_value * _find_cached_def(PyModuleDef *);
static Py_ssize_t _get_cached_module_index(struct extensions_cache_value *);
#endif

static Py_ssize_t
_get_module_index_from_def(PyModuleDef *def)
{
    Py_ssize_t index = def->m_base.m_index;
#ifndef NDEBUG
    struct extensions_cache_value *cached = _find_cached_def(def);
    assert(cached == NULL || index == _get_cached_module_index(cached));
#endif
    return index;
}

static void
_set_module_index(PyModuleDef *def, Py_ssize_t index)
{
    assert(index > 0);
    if (index == def->m_base.m_index) {
        /* There's nothing to do. */
    }
    else if (def->m_base.m_index == 0) {
        /* It should have been initialized by PyModuleDef_Init().
         * We assert here to catch this in dev, but keep going otherwise. */
        assert(def->m_base.m_index != 0);
        def->m_base.m_index = index;
    }
    else {
        /* It was already set for a different module.
         * We replace the old value. */
        assert(def->m_base.m_index > 0);
        def->m_base.m_index = index;
    }
}

static const char *
_modules_by_index_check(PyInterpreterState *interp, Py_ssize_t index)
{
    if (index <= 0) {
        return "invalid module index";
    }
    if (MODULES_BY_INDEX(interp) == NULL) {
        return "Interpreters module-list not accessible.";
    }
    if (index >= PyList_GET_SIZE(MODULES_BY_INDEX(interp))) {
        return "Module index out of bounds.";
    }
    return NULL;
}

static PyObject *
_modules_by_index_get(PyInterpreterState *interp, Py_ssize_t index)
{
    if (_modules_by_index_check(interp, index) != NULL) {
        return NULL;
    }
    PyObject *res = PyList_GET_ITEM(MODULES_BY_INDEX(interp), index);
    return res==Py_None ? NULL : res;
}

static int
_modules_by_index_set(PyInterpreterState *interp,
                      Py_ssize_t index, PyObject *module)
{
    assert(index > 0);

    if (MODULES_BY_INDEX(interp) == NULL) {
        MODULES_BY_INDEX(interp) = PyList_New(0);
        if (MODULES_BY_INDEX(interp) == NULL) {
            return -1;
        }
    }

    while (PyList_GET_SIZE(MODULES_BY_INDEX(interp)) <= index) {
        if (PyList_Append(MODULES_BY_INDEX(interp), Py_None) < 0) {
            return -1;
        }
    }

    return PyList_SetItem(MODULES_BY_INDEX(interp), index, Py_NewRef(module));
}

static int
_modules_by_index_clear_one(PyInterpreterState *interp, Py_ssize_t index)
{
    const char *err = _modules_by_index_check(interp, index);
    if (err != NULL) {
        Py_FatalError(err);
        return -1;
    }
    return PyList_SetItem(MODULES_BY_INDEX(interp), index, Py_NewRef(Py_None));
}


PyObject*
PyState_FindModule(PyModuleDef* module)
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    if (module->m_slots) {
        return NULL;
    }
    Py_ssize_t index = _get_module_index_from_def(module);
    return _modules_by_index_get(interp, index);
}

/* _PyState_AddModule() has been completely removed from the C-API
   (and was removed from the limited API in 3.6).  However, we're
   playing it safe and keeping it around for any stable ABI extensions
   built against 3.2-3.5. */
int
_PyState_AddModule(PyThreadState *tstate, PyObject* module, PyModuleDef* def)
{
    if (!def) {
        assert(_PyErr_Occurred(tstate));
        return -1;
    }
    if (def->m_slots) {
        _PyErr_SetString(tstate,
                         PyExc_SystemError,
                         "PyState_AddModule called on module with slots");
        return -1;
    }
    assert(def->m_slots == NULL);
    Py_ssize_t index = _get_module_index_from_def(def);
    return _modules_by_index_set(tstate->interp, index, module);
}

int
PyState_AddModule(PyObject* module, PyModuleDef* def)
{
    if (!def) {
        Py_FatalError("module definition is NULL");
        return -1;
    }

    PyThreadState *tstate = _PyThreadState_GET();
    if (def->m_slots) {
        _PyErr_SetString(tstate,
                         PyExc_SystemError,
                         "PyState_AddModule called on module with slots");
        return -1;
    }

    PyInterpreterState *interp = tstate->interp;
    Py_ssize_t index = _get_module_index_from_def(def);
    if (MODULES_BY_INDEX(interp) &&
        index < PyList_GET_SIZE(MODULES_BY_INDEX(interp)) &&
        module == PyList_GET_ITEM(MODULES_BY_INDEX(interp), index))
    {
        _Py_FatalErrorFormat(__func__, "module %p already added", module);
        return -1;
    }

    assert(def->m_slots == NULL);
    return _modules_by_index_set(interp, index, module);
}

int
PyState_RemoveModule(PyModuleDef* def)
{
    PyThreadState *tstate = _PyThreadState_GET();
    if (def->m_slots) {
        _PyErr_SetString(tstate,
                         PyExc_SystemError,
                         "PyState_RemoveModule called on module with slots");
        return -1;
    }
    Py_ssize_t index = _get_module_index_from_def(def);
    return _modules_by_index_clear_one(tstate->interp, index);
}


// Used by finalize_modules()
void
_PyImport_ClearModulesByIndex(PyInterpreterState *interp)
{
    if (!MODULES_BY_INDEX(interp)) {
        return;
    }

    Py_ssize_t i;
    for (i = 0; i < PyList_GET_SIZE(MODULES_BY_INDEX(interp)); i++) {
        PyObject *m = PyList_GET_ITEM(MODULES_BY_INDEX(interp), i);
        if (PyModule_Check(m)) {
            /* cleanup the saved copy of module dicts */
            PyModuleDef *md = PyModule_GetDef(m);
            if (md) {
                // XXX Do this more carefully.  The dict might be owned
                // by another interpreter.
                Py_CLEAR(md->m_base.m_copy);
            }
        }
    }

    /* Setting modules_by_index to NULL could be dangerous, so we
       clear the list instead. */
    if (PyList_SetSlice(MODULES_BY_INDEX(interp),
                        0, PyList_GET_SIZE(MODULES_BY_INDEX(interp)),
                        NULL)) {
        PyErr_FormatUnraisable("Exception ignored while "
                               "clearing interpreters module list");
    }
}


/*********************/
/* extension modules */
/*********************/

/*
    It may help to have a big picture view of what happens
    when an extension is loaded.  This includes when it is imported
    for the first time.

    Here's a summary, using importlib._bootstrap._load() as a starting point.

    1.  importlib._bootstrap._load()
    2.    _load():  acquire import lock
    3.    _load() -> importlib._bootstrap._load_unlocked()
    4.      _load_unlocked() -> importlib._bootstrap.module_from_spec()
    5.        module_from_spec() -> ExtensionFileLoader.create_module()
    6.          create_module() -> _imp.create_dynamic()
                    (see below)
    7.        module_from_spec() -> importlib._bootstrap._init_module_attrs()
    8.      _load_unlocked():  sys.modules[name] = module
    9.      _load_unlocked() -> ExtensionFileLoader.exec_module()
    10.       exec_module() -> _imp.exec_dynamic()
                  (see below)
    11.   _load():  release import lock


    ...for single-phase init modules, where m_size == -1:

    (6). first time  (not found in _PyRuntime.imports.extensions):
       A. _imp_create_dynamic_impl() -> import_find_extension()
       B. _imp_create_dynamic_impl() -> _PyImport_GetModuleExportHooks()
       C.   _PyImport_GetModuleExportHooks():  load <module init func>
       D. _imp_create_dynamic_impl() -> import_run_extension()
       E.   import_run_extension() -> _PyImport_RunModInitFunc()
       F.     _PyImport_RunModInitFunc():  call <module init func>
       G.       <module init func> -> PyModule_Create() -> PyModule_Create2()
                                          -> PyModule_CreateInitialized()
       H.         PyModule_CreateInitialized() -> PyModule_New()
       I.         PyModule_CreateInitialized():  allocate mod->md_state
       J.         PyModule_CreateInitialized() -> PyModule_AddFunctions()
       K.         PyModule_CreateInitialized() -> PyModule_SetDocString()
       L.       PyModule_CreateInitialized():  set mod->md_def
       M.       <module init func>:  initialize the module, etc.
       N.   import_run_extension()
                -> _PyImport_CheckSubinterpIncompatibleExtensionAllowed()
       O.   import_run_extension():  set __file__
       P.   import_run_extension() -> update_global_state_for_extension()
       Q.     update_global_state_for_extension():
                      copy __dict__ into def->m_base.m_copy
       R.     update_global_state_for_extension():
                      add it to _PyRuntime.imports.extensions
       S.   import_run_extension() -> finish_singlephase_extension()
       T.     finish_singlephase_extension():
                      add it to interp->imports.modules_by_index
       U.     finish_singlephase_extension():  add it to sys.modules

       Step (Q) is skipped for core modules (sys/builtins).

    (6). subsequent times  (found in _PyRuntime.imports.extensions):
       A. _imp_create_dynamic_impl() -> import_find_extension()
       B.   import_find_extension() -> reload_singlephase_extension()
       C.     reload_singlephase_extension()
                  -> _PyImport_CheckSubinterpIncompatibleExtensionAllowed()
       D.     reload_singlephase_extension() -> import_add_module()
       E.       if name in sys.modules:  use that module
       F.       else:
                  1. import_add_module() -> PyModule_NewObject()
                  2. import_add_module():  set it on sys.modules
       G.     reload_singlephase_extension():  copy the "m_copy" dict into __dict__
       H.     reload_singlephase_extension():  add to modules_by_index

    (10). (every time):
       A. noop


    ...for single-phase init modules, where m_size >= 0:

    (6). not main interpreter and never loaded there - every time  (not found in _PyRuntime.imports.extensions):
       A-P. (same as for m_size == -1)
       Q.     _PyImport_RunModInitFunc():  set def->m_base.m_init
       R. (skipped)
       S-U. (same as for m_size == -1)

    (6). main interpreter - first time  (not found in _PyRuntime.imports.extensions):
       A-P. (same as for m_size == -1)
       Q.     _PyImport_RunModInitFunc():  set def->m_base.m_init
       R-U. (same as for m_size == -1)

    (6). subsequent times  (found in _PyRuntime.imports.extensions):
       A. _imp_create_dynamic_impl() -> import_find_extension()
       B.   import_find_extension() -> reload_singlephase_extension()
       C.     reload_singlephase_extension()
                  -> _PyImport_CheckSubinterpIncompatibleExtensionAllowed()
       D.     reload_singlephase_extension():  call def->m_base.m_init  (see above)
       E.     reload_singlephase_extension():  add the module to sys.modules
       F.     reload_singlephase_extension():  add to modules_by_index

    (10). every time:
       A. noop


    ...for multi-phase init modules from PyModInit_* (PyModuleDef):

    (6). every time:
       A. _imp_create_dynamic_impl() -> import_find_extension()  (not found)
       B. _imp_create_dynamic_impl() -> _PyImport_GetModuleExportHooks()
       C.   _PyImport_GetModuleExportHooks():  load <module init func>
       D. _imp_create_dynamic_impl() -> import_run_extension()
       E.   import_run_extension() -> _PyImport_RunModInitFunc()
       F.     _PyImport_RunModInitFunc():  call <module init func>
       G.   import_run_extension() -> PyModule_FromDefAndSpec()

       PyModule_FromDefAndSpec():

       H.      PyModule_FromDefAndSpec(): gather/check moduledef slots
       I.      if there's a Py_mod_create slot:
                 1. PyModule_FromDefAndSpec():  call its function
       J.      else:
                 1. PyModule_FromDefAndSpec() -> PyModule_NewObject()
       K:      PyModule_FromDefAndSpec():  set mod->md_def
       L.      PyModule_FromDefAndSpec() -> _add_methods_to_object()
       M.      PyModule_FromDefAndSpec() -> PyModule_SetDocString()

    (10). every time:
       A. _imp_exec_dynamic_impl() -> exec_builtin_or_dynamic()
       B.   if mod->md_state == NULL (including if m_size == 0):
            1. exec_builtin_or_dynamic() -> PyModule_Exec()
            2.   PyModule_Exec():  allocate mod->md_state
            3.   if there's a Py_mod_exec slot:
                 1. PyModule_Exec():  call its function


    ...for multi-phase init modules from PyModExport_* (slots array):

    (6). every time:

       A. _imp_create_dynamic_impl() -> import_find_extension()  (not found)
       B. _imp_create_dynamic_impl() -> _PyImport_GetModuleExportHooks()
       C.   _PyImport_GetModuleExportHooks():  load <module export func>
       D. _imp_create_dynamic_impl() -> import_run_modexport()
       E.     import_run_modexport():  call <module init func>
       F.   import_run_modexport() -> PyModule_FromSlotsAndSpec()
       G.     PyModule_FromSlotsAndSpec(): create temporary PyModuleDef-like
       H.       PyModule_FromSlotsAndSpec() -> PyModule_FromDefAndSpec()

       (PyModule_FromDefAndSpec behaves as for PyModInit_*, above)

    (10). every time: as for PyModInit_*, above

 */


/* Make sure name is fully qualified.

   This is a bit of a hack: when the shared library is loaded,
   the module name is "package.module", but the module calls
   PyModule_Create*() with just "module" for the name.  The shared
   library loader squirrels away the true name of the module in
   _PyRuntime.imports.pkgcontext, and PyModule_Create*() will
   substitute this (if the name actually matches).
*/

static _Py_thread_local const char *pkgcontext = NULL;
# define PKGCONTEXT pkgcontext

const char *
_PyImport_ResolveNameWithPackageContext(const char *name)
{
    if (PKGCONTEXT != NULL) {
        const char *p = strrchr(PKGCONTEXT, '.');
        if (p != NULL && strcmp(name, p+1) == 0) {
            name = PKGCONTEXT;
            PKGCONTEXT = NULL;
        }
    }
    return name;
}

const char *
_PyImport_SwapPackageContext(const char *newcontext)
{
    const char *oldcontext = PKGCONTEXT;
    PKGCONTEXT = newcontext;
    return oldcontext;
}

#ifdef HAVE_DLOPEN
int
_PyImport_GetDLOpenFlags(PyInterpreterState *interp)
{
    return DLOPENFLAGS(interp);
}

void
_PyImport_SetDLOpenFlags(PyInterpreterState *interp, int new_val)
{
    DLOPENFLAGS(interp) = new_val;
}
#endif  // HAVE_DLOPEN


/* Common implementation for _imp.exec_dynamic and _imp.exec_builtin */
static int
exec_builtin_or_dynamic(PyObject *mod) {
    void *state;

    if (!PyModule_Check(mod)) {
        return 0;
    }

    state = PyModule_GetState(mod);
    if (state) {
        /* Already initialized; skip reload */
        return 0;
    }

    return PyModule_Exec(mod);
}


static int clear_singlephase_extension(PyInterpreterState *interp,
                                       PyObject *name, PyObject *filename);

// Currently, this is only used for testing.
// (See _testinternalcapi.clear_extension().)
// If adding another use, be careful about modules that import themselves
// recursively (see gh-123880).
int
_PyImport_ClearExtension(PyObject *name, PyObject *filename)
{
    PyInterpreterState *interp = _PyInterpreterState_GET();

    /* Clearing a module's C globals is up to the module. */
    if (clear_singlephase_extension(interp, name, filename) < 0) {
        return -1;
    }

    // In the future we'll probably also make sure the extension's
    // file handle (and DL handle) is closed (requires saving it).

    return 0;
}


/*****************************/
/* single-phase init modules */
/*****************************/

/*
We support a number of kinds of single-phase init builtin/extension modules:

* "basic"
    * no module state (PyModuleDef.m_size == -1)
    * does not support repeated init (we use PyModuleDef.m_base.m_copy)
    * may have process-global state
    * the module's def is cached in _PyRuntime.imports.extensions,
      by (name, filename)
* "reinit"
    * no module state (PyModuleDef.m_size == 0)
    * supports repeated init (m_copy is never used)
    * should not have any process-global state
    * its def is never cached in _PyRuntime.imports.extensions
      (except, currently, under the main interpreter, for some reason)
* "with state"  (almost the same as reinit)
    * has module state (PyModuleDef.m_size > 0)
    * supports repeated init (m_copy is never used)
    * should not have any process-global state
    * its def is never cached in _PyRuntime.imports.extensions
      (except, currently, under the main interpreter, for some reason)

There are also variants within those classes:

* two or more modules share a PyModuleDef
    * a module's init func uses another module's PyModuleDef
    * a module's init func calls another's module's init func
    * a module's init "func" is actually a variable statically initialized
      to another module's init func
* two or modules share "methods"
    * a module's init func copies another module's PyModuleDef
      (with a different name)
* (basic-only) two or modules share process-global state

In the first case, where modules share a PyModuleDef, the following
notable weirdness happens:

* the module's __name__ matches the def, not the requested name
* the last module (with the same def) to be imported for the first time wins
    * returned by PyState_Find_Module() (via interp->modules_by_index)
    * (non-basic-only) its init func is used when re-loading any of them
      (via the def's m_init)
    * (basic-only) the copy of its __dict__ is used when re-loading any of them
      (via the def's m_copy)

However, the following happens as expected:

* a new module object (with its own __dict__) is created for each request
* the module's __spec__ has the requested name
* the loaded module is cached in sys.modules under the requested name
* the m_index field of the shared def is not changed,
  so at least PyState_FindModule() will always look in the same place

For "basic" modules there are other quirks:

* (whether sharing a def or not) when loaded the first time,
  m_copy is set before _init_module_attrs() is called
  in importlib._bootstrap.module_from_spec(),
  so when the module is re-loaded, the previous value
  for __wpec__ (and others) is reset, possibly unexpectedly.

Generally, when multiple interpreters are involved, some of the above
gets even messier.
*/

static inline void
extensions_lock_acquire(void)
{
    PyMutex_Lock(&_PyRuntime.imports.extensions.mutex);
}

static inline void
extensions_lock_release(void)
{
    PyMutex_Unlock(&_PyRuntime.imports.extensions.mutex);
}


/* Magic for extension modules (built-in as well as dynamically
   loaded).  To prevent initializing an extension module more than
   once, we keep a static dictionary 'extensions' keyed by the tuple
   (module name, module name)  (for built-in modules) or by
   (filename, module name) (for dynamically loaded modules), containing these
   modules.  A copy of the module's dictionary is stored by calling
   fix_up_extension() immediately after the module initialization
   function succeeds.  A copy can be retrieved from there by calling
   import_find_extension().

   Modules which do support multiple initialization set their m_size
   field to a non-negative number (indicating the size of the
   module-specific state). They are still recorded in the extensions
   dictionary, to avoid loading shared libraries twice.
*/

typedef struct cached_m_dict {
    /* A shallow copy of the original module's __dict__. */
    PyObject *copied;
    /* The interpreter that owns the copy. */
    int64_t interpid;
} *cached_m_dict_t;

struct extensions_cache_value {
    PyModuleDef *def;

    /* The function used to re-initialize the module.
       This is only set for legacy (single-phase init) extension modules
       and only used for those that support multiple initializations
       (m_size >= 0).
       It is set by update_global_state_for_extension(). */
    PyModInitFunction m_init;

    /* The module's index into its interpreter's modules_by_index cache.
       This is set for all extension modules but only used for legacy ones.
       (See PyInterpreterState.modules_by_index for more info.) */
    Py_ssize_t m_index;

    /* A copy of the module's __dict__ after the first time it was loaded.
       This is only set/used for legacy modules that do not support
       multiple initializations.
       It is set exclusively by fixup_cached_def(). */
    cached_m_dict_t m_dict;
    struct cached_m_dict _m_dict;

    _Py_ext_module_origin origin;

#ifdef Py_GIL_DISABLED
    /* The module's md_requires_gil member, for legacy modules that are
     * reinitialized from m_dict rather than calling their initialization
     * function again. */
    bool md_requires_gil;
#endif
};

static struct extensions_cache_value *
alloc_extensions_cache_value(void)
{
    struct extensions_cache_value *value
            = PyMem_RawMalloc(sizeof(struct extensions_cache_value));
    if (value == NULL) {
        PyErr_NoMemory();
        return NULL;
    }
    *value = (struct extensions_cache_value){0};
    return value;
}

static void
free_extensions_cache_value(struct extensions_cache_value *value)
{
    PyMem_RawFree(value);
}

static Py_ssize_t
_get_cached_module_index(struct extensions_cache_value *cached)
{
    assert(cached->m_index > 0);
    return cached->m_index;
}

static void
fixup_cached_def(struct extensions_cache_value *value)
{
    /* For the moment, the values in the def's m_base may belong
     * to another module, and we're replacing them here.  This can
     * cause problems later if the old module is reloaded.
     *
     * Also, we don't decref any old cached values first when we
     * replace them here, in case we need to restore them in the
     * near future.  Instead, the caller is responsible for wrapping
     * this up by calling cleanup_old_cached_def() or
     * restore_old_cached_def() if there was an error. */
    PyModuleDef *def = value->def;
    assert(def != NULL);

    /* We assume that all module defs are statically allocated
       and will never be freed.  Otherwise, we would incref here. */
    _Py_SetImmortalUntracked((PyObject *)def);

    def->m_base.m_init = value->m_init;

    assert(value->m_index > 0);
    _set_module_index(def, value->m_index);

    /* Different modules can share the same def, so we can't just
     * expect m_copy to be NULL. */
    assert(def->m_base.m_copy == NULL
           || def->m_base.m_init == NULL
           || value->m_dict != NULL);
    if (value->m_dict != NULL) {
        assert(value->m_dict->copied != NULL);
        /* As noted above, we don't first decref the old value, if any. */
        def->m_base.m_copy = Py_NewRef(value->m_dict->copied);
    }
}

static void
restore_old_cached_def(PyModuleDef *def, PyModuleDef_Base *oldbase)
{
    def->m_base = *oldbase;
}

static void
cleanup_old_cached_def(PyModuleDef_Base *oldbase)
{
    Py_XDECREF(oldbase->m_copy);
}

static void
del_cached_def(struct extensions_cache_value *value)
{
    /* If we hadn't made the stored defs immortal, we would decref here.
       However, this decref would be problematic if the module def were
       dynamically allocated, it were the last ref, and this function
       were called with an interpreter other than the def's owner. */
    assert(value->def == NULL || _Py_IsImmortal(value->def));

    Py_XDECREF(value->def->m_base.m_copy);
    value->def->m_base.m_copy = NULL;
}

static int
init_cached_m_dict(struct extensions_cache_value *value, PyObject *m_dict)
{
    assert(value != NULL);
    /* This should only have been called without an m_dict already set. */
    assert(value->m_dict == NULL);
    if (m_dict == NULL) {
        return 0;
    }
    assert(PyDict_Check(m_dict));
    assert(value->origin != _Py_ext_module_origin_CORE);

    PyInterpreterState *interp = _PyInterpreterState_GET();
    assert(!is_interpreter_isolated(interp));

    /* XXX gh-88216: The copied dict is owned by the current
     * interpreter.  That's a problem if the interpreter has
     * its own obmalloc state or if the module is successfully
     * imported into such an interpreter.  If the interpreter
     * has its own GIL then there may be data races and
     * PyImport_ClearModulesByIndex() can crash.  Normally,
     * a single-phase init module cannot be imported in an
     * isolated interpreter, but there are ways around that.
     * Hence, heere be dragons!  Ideally we would instead do
     * something like make a read-only, immortal copy of the
     * dict using PyMem_RawMalloc() and store *that* in m_copy.
     * Then we'd need to make sure to clear that when the
     * runtime is finalized, rather than in
     * PyImport_ClearModulesByIndex(). */
    PyObject *copied = PyDict_Copy(m_dict);
    if (copied == NULL) {
        /* We expect this can only be "out of memory". */
        return -1;
    }
    // XXX We may want to make the copy immortal.

    value->_m_dict = (struct cached_m_dict){
        .copied=copied,
        .interpid=PyInterpreterState_GetID(interp),
    };

    value->m_dict = &value->_m_dict;
    return 0;
}

static void
del_cached_m_dict(struct extensions_cache_value *value)
{
    if (value->m_dict != NULL) {
        assert(value->m_dict == &value->_m_dict);
        assert(value->m_dict->copied != NULL);
        /* In the future we can take advantage of m_dict->interpid
         * to decref the dict using the owning interpreter. */
        Py_XDECREF(value->m_dict->copied);
        value->m_dict = NULL;
    }
}

static PyObject * get_core_module_dict(
        PyInterpreterState *interp, PyObject *name, PyObject *path);

static PyObject *
get_cached_m_dict(struct extensions_cache_value *value,
                  PyObject *name, PyObject *path)
{
    assert(value != NULL);
    PyInterpreterState *interp = _PyInterpreterState_GET();
    /* It might be a core module (e.g. sys & builtins),
       for which we don't cache m_dict. */
    if (value->origin == _Py_ext_module_origin_CORE) {
        return get_core_module_dict(interp, name, path);
    }
    assert(value->def != NULL);
    // XXX Switch to value->m_dict.
    PyObject *m_dict = value->def->m_base.m_copy;
    Py_XINCREF(m_dict);
    return m_dict;
}

static void
del_extensions_cache_value(void *raw)
{
    struct extensions_cache_value *value = raw;
    if (value != NULL) {
        del_cached_m_dict(value);
        del_cached_def(value);
        free_extensions_cache_value(value);
    }
}

static void *
hashtable_key_from_2_strings(PyObject *str1, PyObject *str2, const char sep)
{
    const char *str1_data = _PyUnicode_AsUTF8NoNUL(str1);
    const char *str2_data = _PyUnicode_AsUTF8NoNUL(str2);
    if (str1_data == NULL || str2_data == NULL) {
        return NULL;
    }
    Py_ssize_t str1_len = strlen(str1_data);
    Py_ssize_t str2_len = strlen(str2_data);

    /* Make sure sep and the NULL byte won't cause an overflow. */
    assert(SIZE_MAX - str1_len - str2_len > 2);
    size_t size = str1_len + 1 + str2_len + 1;

    // XXX Use a buffer if it's a temp value (every case but "set").
    char *key = PyMem_RawMalloc(size);
    if (key == NULL) {
        PyErr_NoMemory();
        return NULL;
    }

    memcpy(key, str1_data, str1_len);
    key[str1_len] = sep;
    memcpy(key + str1_len + 1, str2_data, str2_len);
    key[size - 1] = '\0';
    assert(strlen(key) == size - 1);
    return key;
}

static Py_uhash_t
hashtable_hash_str(const void *key)
{
    return Py_HashBuffer(key, strlen((const char *)key));
}

static int
hashtable_compare_str(const void *key1, const void *key2)
{
    return strcmp((const char *)key1, (const char *)key2) == 0;
}

static void
hashtable_destroy_str(void *ptr)
{
    PyMem_RawFree(ptr);
}

#ifndef NDEBUG
struct hashtable_next_match_def_data {
    PyModuleDef *def;
    struct extensions_cache_value *matched;
};

static int
hashtable_next_match_def(_Py_hashtable_t *ht,
                         const void *key, const void *value, void *user_data)
{
    if (value == NULL) {
        /* It was previously deleted. */
        return 0;
    }
    struct hashtable_next_match_def_data *data
            = (struct hashtable_next_match_def_data *)user_data;
    struct extensions_cache_value *cur
            = (struct extensions_cache_value *)value;
    if (cur->def == data->def) {
        data->matched = cur;
        return 1;
    }
    return 0;
}

static struct extensions_cache_value *
_find_cached_def(PyModuleDef *def)
{
    struct hashtable_next_match_def_data data = {0};
    (void)_Py_hashtable_foreach(
            EXTENSIONS.hashtable, hashtable_next_match_def, &data);
    return data.matched;
}
#endif

#define HTSEP ':'

static int
_extensions_cache_init(void)
{
    _Py_hashtable_allocator_t alloc = {PyMem_RawMalloc, PyMem_RawFree};
    EXTENSIONS.hashtable = _Py_hashtable_new_full(
        hashtable_hash_str,
        hashtable_compare_str,
        hashtable_destroy_str,  // key
        del_extensions_cache_value,  // value
        &alloc
    );
    if (EXTENSIONS.hashtable == NULL) {
        PyErr_NoMemory();
        return -1;
    }
    return 0;
}

static _Py_hashtable_entry_t *
_extensions_cache_find_unlocked(PyObject *path, PyObject *name,
                                void **p_key)
{
    if (EXTENSIONS.hashtable == NULL) {
        return NULL;
    }
    void *key = hashtable_key_from_2_strings(path, name, HTSEP);
    if (key == NULL) {
        return NULL;
    }
    _Py_hashtable_entry_t *entry =
            _Py_hashtable_get_entry(EXTENSIONS.hashtable, key);
    if (p_key != NULL) {
        *p_key = key;
    }
    else {
        hashtable_destroy_str(key);
    }
    return entry;
}

/* This can only fail with "out of memory". */
static struct extensions_cache_value *
_extensions_cache_get(PyObject *path, PyObject *name)
{
    struct extensions_cache_value *value = NULL;
    extensions_lock_acquire();

    _Py_hashtable_entry_t *entry =
            _extensions_cache_find_unlocked(path, name, NULL);
    if (entry == NULL) {
        /* It was never added. */
        goto finally;
    }
    value = (struct extensions_cache_value *)entry->value;

finally:
    extensions_lock_release();
    return value;
}

/* This can only fail with "out of memory". */
static struct extensions_cache_value *
_extensions_cache_set(PyObject *path, PyObject *name,
                      PyModuleDef *def, PyModInitFunction m_init,
                      Py_ssize_t m_index, PyObject *m_dict,
                      _Py_ext_module_origin origin, bool requires_gil)
{
    struct extensions_cache_value *value = NULL;
    void *key = NULL;
    struct extensions_cache_value *newvalue = NULL;
    PyModuleDef_Base olddefbase = def->m_base;

    assert(def != NULL);
    assert(m_init == NULL || m_dict == NULL);
    /* We expect the same symbol to be used and the shared object file
     * to have remained loaded, so it must be the same pointer. */
    assert(def->m_base.m_init == NULL || def->m_base.m_init == m_init);
    /* For now we don't worry about comparing value->m_copy. */
    assert(def->m_base.m_copy == NULL || m_dict != NULL);
    assert((origin == _Py_ext_module_origin_DYNAMIC) == (name != path));
    assert(origin != _Py_ext_module_origin_CORE || m_dict == NULL);

    extensions_lock_acquire();

    if (EXTENSIONS.hashtable == NULL) {
        if (_extensions_cache_init() < 0) {
            goto finally;
        }
    }

    /* Create a cached value to populate for the module. */
    _Py_hashtable_entry_t *entry =
            _extensions_cache_find_unlocked(path, name, &key);
    value = entry == NULL
        ? NULL
        : (struct extensions_cache_value *)entry->value;
    if (value != NULL) {
        /* gh-123880: If there's an existing cache value, it means a module is
         * being imported recursively from its PyInit_* or Py_mod_* function.
         * (That function presumably handles returning a partially
         *  constructed module in such a case.)
         * We can reuse the existing cache value; it is owned by the cache.
         * (Entries get removed from it in exceptional circumstances,
         *  after interpreter shutdown, and in runtime shutdown.)
         */
        goto finally_oldvalue;
    }
    newvalue = alloc_extensions_cache_value();
    if (newvalue == NULL) {
        goto finally;
    }

    /* Populate the new cache value data. */
    *newvalue = (struct extensions_cache_value){
        .def=def,
        .m_init=m_init,
        .m_index=m_index,
        /* m_dict is set by set_cached_m_dict(). */
        .origin=origin,
#ifdef Py_GIL_DISABLED
        .md_requires_gil=requires_gil,
#endif
    };
#ifndef Py_GIL_DISABLED
    (void)requires_gil;
#endif
    if (init_cached_m_dict(newvalue, m_dict) < 0) {
        goto finally;
    }
    fixup_cached_def(newvalue);

    if (entry == NULL) {
        /* It was never added. */
        if (_Py_hashtable_set(EXTENSIONS.hashtable, key, newvalue) < 0) {
            PyErr_NoMemory();
            goto finally;
        }
        /* The hashtable owns the key now. */
        key = NULL;
    }
    else if (value == NULL) {
        /* It was previously deleted. */
        entry->value = newvalue;
    }
    else {
        /* We are updating the entry for an existing module. */
        /* We expect def to be static, so it must be the same pointer. */
        assert(value->def == def);
        /* We expect the same symbol to be used and the shared object file
         * to have remained loaded, so it must be the same pointer. */
        assert(value->m_init == m_init);
        /* The same module can't switch between caching __dict__ and not. */
        assert((value->m_dict == NULL) == (m_dict == NULL));
        /* This shouldn't ever happen. */
        Py_UNREACHABLE();
    }

    value = newvalue;

finally:
    if (value == NULL) {
        restore_old_cached_def(def, &olddefbase);
        if (newvalue != NULL) {
            del_extensions_cache_value(newvalue);
        }
    }
    else {
        cleanup_old_cached_def(&olddefbase);
    }

finally_oldvalue:
    extensions_lock_release();
    if (key != NULL) {
        hashtable_destroy_str(key);
    }

    return value;
}

static void
_extensions_cache_delete(PyObject *path, PyObject *name)
{
    extensions_lock_acquire();

    if (EXTENSIONS.hashtable == NULL) {
        /* It was never added. */
        goto finally;
    }

    _Py_hashtable_entry_t *entry =
            _extensions_cache_find_unlocked(path, name, NULL);
    if (entry == NULL) {
        /* It was never added. */
        goto finally;
    }
    if (entry->value == NULL) {
        /* It was already removed. */
        goto finally;
    }
    struct extensions_cache_value *value = entry->value;
    entry->value = NULL;

    del_extensions_cache_value(value);

finally:
    extensions_lock_release();
}

static void
_extensions_cache_clear_all(void)
{
    /* The runtime (i.e. main interpreter) must be finalizing,
       so we don't need to worry about the lock. */
    _Py_hashtable_destroy(EXTENSIONS.hashtable);
    EXTENSIONS.hashtable = NULL;
}

#undef HTSEP


static bool
check_multi_interp_extensions(PyInterpreterState *interp)
{
    int override = OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK(interp);
    if (override < 0) {
        return false;
    }
    else if (override > 0) {
        return true;
    }
    else if (_PyInterpreterState_HasFeature(
                interp, Py_RTFLAGS_MULTI_INTERP_EXTENSIONS)) {
        return true;
    }
    return false;
}

int
_PyImport_CheckSubinterpIncompatibleExtensionAllowed(const char *name)
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    if (check_multi_interp_extensions(interp)) {
        assert(!_Py_IsMainInterpreter(interp));
        PyErr_Format(PyExc_ImportError,
                     "module %s does not support loading in subinterpreters",
                     name);
        return -1;
    }
    return 0;
}

#ifdef Py_GIL_DISABLED
int
_PyImport_CheckGILForModule(PyObject* module, PyObject *module_name)
{
    PyThreadState *tstate = _PyThreadState_GET();
    if (module == NULL) {
        _PyEval_DisableGIL(tstate);
        return 0;
    }

    if (!PyModule_Check(module) ||
        ((PyModuleObject *)module)->md_requires_gil)
    {
        if (PyModule_Check(module)) {
            assert(((PyModuleObject *)module)->md_token_is_def);
        }
        if (_PyImport_EnableGILAndWarn(tstate, module_name) < 0) {
            return -1;
        }
    }
    else {
        _PyEval_DisableGIL(tstate);
    }

    return 0;
}

int
_PyImport_EnableGILAndWarn(PyThreadState *tstate, PyObject *module_name)
{
    if (_PyEval_EnableGILPermanent(tstate)) {
        return PyErr_WarnFormat(
            PyExc_RuntimeWarning,
            1,
            "The global interpreter lock (GIL) has been enabled to load "
            "module '%U', which has not declared that it can run safely "
            "without the GIL. To override this behavior and keep the GIL "
            "disabled (at your own risk), run with PYTHON_GIL=0 or -Xgil=0.",
            module_name
        );
    }
    const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
    if (config->enable_gil == _PyConfig_GIL_DEFAULT && config->verbose) {
        PySys_FormatStderr("# loading module '%U', which requires the GIL\n",
                            module_name);
    }
    return 0;
}
#endif

static PyThreadState *
switch_to_main_interpreter(PyThreadState *tstate)
{
    if (_Py_IsMainInterpreter(tstate->interp)) {
        return tstate;
    }
    PyThreadState *main_tstate = _PyThreadState_NewBound(
            _PyInterpreterState_Main(), _PyThreadState_WHENCE_EXEC);
    if (main_tstate == NULL) {
        return NULL;
    }
#ifndef NDEBUG
    PyThreadState *old_tstate = PyThreadState_Swap(main_tstate);
    assert(old_tstate == tstate);
#else
    (void)PyThreadState_Swap(main_tstate);
#endif
    return main_tstate;
}

static void
switch_back_from_main_interpreter(PyThreadState *tstate,
                                  PyThreadState *main_tstate,
                                  PyObject *tempobj)
{
    assert(main_tstate == PyThreadState_GET());
    assert(_Py_IsMainInterpreter(main_tstate->interp));
    assert(tstate->interp != main_tstate->interp);

    /* Handle any exceptions, which we cannot propagate directly
     * to the subinterpreter. */
    if (PyErr_Occurred()) {
        if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
            /* We trust it will be caught again soon. */
            PyErr_Clear();
        }
        else {
            /* Printing the exception should be sufficient. */
            PyErr_PrintEx(0);
        }
    }

    Py_XDECREF(tempobj);

    PyThreadState_Clear(main_tstate);
    (void)PyThreadState_Swap(tstate);
    PyThreadState_Delete(main_tstate);
}

static PyObject *
get_core_module_dict(PyInterpreterState *interp,
                     PyObject *name, PyObject *path)
{
    /* Only builtin modules are core. */
    if (path == name) {
        assert(!PyErr_Occurred());
        if (PyUnicode_CompareWithASCIIString(name, "sys") == 0) {
            return Py_NewRef(interp->sysdict_copy);
        }
        assert(!PyErr_Occurred());
        if (PyUnicode_CompareWithASCIIString(name, "builtins") == 0) {
            return Py_NewRef(interp->builtins_copy);
        }
        assert(!PyErr_Occurred());
    }
    return NULL;
}

#ifndef NDEBUG
static inline int
is_core_module(PyInterpreterState *interp, PyObject *name, PyObject *path)
{
    /* This might be called before the core dict copies are in place,
       so we can't rely on get_core_module_dict() here. */
    if (path == name) {
        if (PyUnicode_CompareWithASCIIString(name, "sys") == 0) {
            return 1;
        }
        if (PyUnicode_CompareWithASCIIString(name, "builtins") == 0) {
            return 1;
        }
    }
    return 0;
}


static _Py_ext_module_kind
_get_extension_kind(PyModuleDef *def, bool check_size)
{
    _Py_ext_module_kind kind;
    if (def == NULL) {
        /* It must be a module created by reload_singlephase_extension()
         * from m_copy.  Ideally we'd do away with this case. */
        kind = _Py_ext_module_kind_SINGLEPHASE;
    }
    else if (def->m_slots != NULL) {
        kind = _Py_ext_module_kind_MULTIPHASE;
    }
    else if (check_size && def->m_size == -1) {
        kind = _Py_ext_module_kind_SINGLEPHASE;
    }
    else if (def->m_base.m_init != NULL) {
        kind = _Py_ext_module_kind_SINGLEPHASE;
    }
    else {
        // This is probably single-phase init, but a multi-phase
        // module *can* have NULL m_slots.
        kind = _Py_ext_module_kind_UNKNOWN;
    }
    return kind;
}

/* The module might not be fully initialized yet
 * and PyModule_FromDefAndSpec() checks m_size
 * so we skip m_size. */
#define assert_multiphase_def(def)                                  \
    do {                                                            \
        _Py_ext_module_kind kind = _get_extension_kind(def, false); \
        assert(kind == _Py_ext_module_kind_MULTIPHASE               \
                /* m_slots can be NULL. */                          \
                || kind == _Py_ext_module_kind_UNKNOWN);            \
    } while (0)

#define assert_singlephase_def(def)                                 \
    do {                                                            \
        _Py_ext_module_kind kind = _get_extension_kind(def, true);  \
        assert(kind == _Py_ext_module_kind_SINGLEPHASE              \
                || kind == _Py_ext_module_kind_UNKNOWN);            \
    } while (0)

#define assert_singlephase(cached)                                          \
    do {                                                                    \
        _Py_ext_module_kind kind = _get_extension_kind(cached->def, true);  \
        assert(kind == _Py_ext_module_kind_SINGLEPHASE);                    \
    } while (0)

#else  /* defined(NDEBUG) */
#define assert_multiphase_def(def)
#define assert_singlephase_def(def)
#define assert_singlephase(cached)
#endif


struct singlephase_global_update {
    PyModInitFunction m_init;
    Py_ssize_t m_index;
    PyObject *m_dict;
    _Py_ext_module_origin origin;
    bool md_requires_gil;
};

static struct extensions_cache_value *
update_global_state_for_extension(PyThreadState *tstate,
                                  PyObject *path, PyObject *name,
                                  PyModuleDef *def,
                                  struct singlephase_global_update *singlephase)
{
    struct extensions_cache_value *cached = NULL;
    PyModInitFunction m_init = NULL;
    PyObject *m_dict = NULL;

    /* Set up for _extensions_cache_set(). */
    if (singlephase == NULL) {
        assert(def->m_base.m_init == NULL);
        assert(def->m_base.m_copy == NULL);
    }
    else {
        if (singlephase->m_init != NULL) {
            assert(singlephase->m_dict == NULL);
            assert(def->m_base.m_copy == NULL);
            assert(def->m_size >= 0);
            /* Remember pointer to module init function. */
            // XXX If two modules share a def then def->m_base will
            // reflect the last one added (here) to the global cache.
            // We should prevent this somehow.  The simplest solution
            // is probably to store m_copy/m_init in the cache along
            // with the def, rather than within the def.
            m_init = singlephase->m_init;
        }
        else if (singlephase->m_dict == NULL) {
            /* It must be a core builtin module. */
            assert(is_core_module(tstate->interp, name, path));
            assert(def->m_size == -1);
            assert(def->m_base.m_copy == NULL);
            assert(def->m_base.m_init == NULL);
        }
        else {
            assert(PyDict_Check(singlephase->m_dict));
            // gh-88216: Extensions and def->m_base.m_copy can be updated
            // when the extension module doesn't support sub-interpreters.
            assert(def->m_size == -1);
            assert(!is_core_module(tstate->interp, name, path));
            assert(PyUnicode_CompareWithASCIIString(name, "sys") != 0);
            assert(PyUnicode_CompareWithASCIIString(name, "builtins") != 0);
            m_dict = singlephase->m_dict;
        }
    }

    /* Add the module's def to the global cache. */
    // XXX Why special-case the main interpreter?
    if (_Py_IsMainInterpreter(tstate->interp) || def->m_size == -1) {
#ifndef NDEBUG
        cached = _extensions_cache_get(path, name);
        assert(cached == NULL || cached->def == def);
#endif
        cached = _extensions_cache_set(
                path, name, def, m_init, singlephase->m_index, m_dict,
                singlephase->origin, singlephase->md_requires_gil);
        if (cached == NULL) {
            // XXX Ignore this error?  Doing so would effectively
            // mark the module as not loadable.
            return NULL;
        }
    }

    return cached;
}

/* For multi-phase init modules, the module is finished
 * by PyModule_FromDefAndSpec(). */
static int
finish_singlephase_extension(PyThreadState *tstate, PyObject *mod,
                             struct extensions_cache_value *cached,
                             PyObject *name, PyObject *modules)
{
    assert(mod != NULL && PyModule_Check(mod));
    assert(cached->def == _PyModule_GetDefOrNull(mod));

    Py_ssize_t index = _get_cached_module_index(cached);
    if (_modules_by_index_set(tstate->interp, index, mod) < 0) {
        return -1;
    }

    if (modules != NULL) {
        if (PyObject_SetItem(modules, name, mod) < 0) {
            return -1;
        }
    }

    return 0;
}


static PyObject *
reload_singlephase_extension(PyThreadState *tstate,
                             struct extensions_cache_value *cached,
                             struct _Py_ext_module_loader_info *info)
{
    PyModuleDef *def = cached->def;
    assert(def != NULL);
    assert_singlephase(cached);
    PyObject *mod = NULL;

    /* It may have been successfully imported previously
       in an interpreter that allows legacy modules
       but is not allowed in the current interpreter. */
    const char *name_buf = PyUnicode_AsUTF8(info->name);
    assert(name_buf != NULL);
    if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) {
        return NULL;
    }

    PyObject *modules = get_modules_dict(tstate, true);
    if (def->m_size == -1) {
        /* Module does not support repeated initialization */
        assert(cached->m_init == NULL);
        assert(def->m_base.m_init == NULL);
        // XXX Copying the cached dict may break interpreter isolation.
        // We could solve this by temporarily acquiring the original
        // interpreter's GIL.
        PyObject *m_copy = get_cached_m_dict(cached, info->name, info->path);
        if (m_copy == NULL) {
            assert(!PyErr_Occurred());
            return NULL;
        }
        mod = import_add_module(tstate, info->name);
        if (mod == NULL) {
            Py_DECREF(m_copy);
            return NULL;
        }
        PyObject *mdict = PyModule_GetDict(mod);
        if (mdict == NULL) {
            Py_DECREF(m_copy);
            Py_DECREF(mod);
            return NULL;
        }
        int rc = PyDict_Update(mdict, m_copy);
        Py_DECREF(m_copy);
        if (rc < 0) {
            Py_DECREF(mod);
            return NULL;
        }
#ifdef Py_GIL_DISABLED
        if (def->m_base.m_copy != NULL) {
            // For non-core modules, fetch the GIL slot that was stored by
            // import_run_extension().
            ((PyModuleObject *)mod)->md_requires_gil = cached->md_requires_gil;
        }
#endif
        /* We can't set mod->md_def if it's missing,
         * because _PyImport_ClearModulesByIndex() might break
         * due to violating interpreter isolation.
         * See the note in set_cached_m_dict().
         * Until that is solved, we leave md_def set to NULL. */
        assert(_PyModule_GetDefOrNull(mod) == NULL
               || _PyModule_GetDefOrNull(mod) == def);
    }
    else {
        assert(cached->m_dict == NULL);
        assert(def->m_base.m_copy == NULL);
        // XXX Use cached->m_init.
        PyModInitFunction p0 = def->m_base.m_init;
        if (p0 == NULL) {
            assert(!PyErr_Occurred());
            return NULL;
        }
        struct _Py_ext_module_loader_result res;
        if (_PyImport_RunModInitFunc(p0, info, &res) < 0) {
            _Py_ext_module_loader_result_apply_error(&res, name_buf);
            return NULL;
        }
        assert(!PyErr_Occurred());
        assert(res.err == NULL);
        assert(res.kind == _Py_ext_module_kind_SINGLEPHASE);
        mod = res.module;
        /* Tchnically, the init function could return a different module def.
         * Then we would probably need to update the global cache.
         * However, we don't expect anyone to change the def. */
        assert(res.def == def);
        _Py_ext_module_loader_result_clear(&res);

        /* Remember the filename as the __file__ attribute */
        if (info->filename != NULL) {
            if (PyModule_AddObjectRef(mod, "__file__", info->filename) < 0) {
                PyErr_Clear(); /* Not important enough to report */
            }
        }

        if (PyObject_SetItem(modules, info->name, mod) == -1) {
            Py_DECREF(mod);
            return NULL;
        }
    }

    Py_ssize_t index = _get_cached_module_index(cached);
    if (_modules_by_index_set(tstate->interp, index, mod) < 0) {
        PyMapping_DelItem(modules, info->name);
        Py_DECREF(mod);
        return NULL;
    }

    return mod;
}

static PyObject *
import_find_extension(PyThreadState *tstate,
                      struct _Py_ext_module_loader_info *info,
                      struct extensions_cache_value **p_cached)
{
    /* Only single-phase init modules will be in the cache. */
    struct extensions_cache_value *cached
            = _extensions_cache_get(info->path, info->name);
    if (cached == NULL) {
        return NULL;
    }
    assert(cached->def != NULL);
    assert_singlephase(cached);
    *p_cached = cached;

    /* It may have been successfully imported previously
       in an interpreter that allows legacy modules
       but is not allowed in the current interpreter. */
    const char *name_buf = PyUnicode_AsUTF8(info->name);
    assert(name_buf != NULL);
    if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) {
        return NULL;
    }

    PyObject *mod = reload_singlephase_extension(tstate, cached, info);
    if (mod == NULL) {
        return NULL;
    }

    int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose;
    if (verbose) {
        PySys_FormatStderr("import %U # previously loaded (%R)\n",
                           info->name, info->path);
    }

    return mod;
}

static PyObject *
import_run_modexport(PyThreadState *tstate, PyModExportFunction ex0,
                     struct _Py_ext_module_loader_info *info,
                     PyObject *spec)
{
    /* This is like import_run_extension, but avoids interpreter switching
     * and code for for single-phase modules.
     */
    PySlot *slots = ex0();
    if (!slots) {
        if (!PyErr_Occurred()) {
            PyErr_Format(
                PyExc_SystemError,
                "module export hook for module %R failed without setting an exception",
                info->name);
        }
        return NULL;
    }
    if (PyErr_Occurred()) {
        PyErr_Format(
            PyExc_SystemError,
            "module export hook for module %R raised unreported exception",
            info->name);
    }
    PyObject *result = PyModule_FromSlotsAndSpec(slots, spec);
    if (!result) {
        return NULL;
    }
    if (PyModule_Check(result)) {
        PyModuleObject *mod = (PyModuleObject *)result;
        if (mod && !mod->md_token) {
            mod->md_token = slots;
        }
    }
    return result;
}

static PyObject *
import_run_extension(PyThreadState *tstate, PyModInitFunction p0,
                     struct _Py_ext_module_loader_info *info,
                     PyObject *spec, PyObject *modules)
{
    /* Core modules go through _PyImport_FixupBuiltin(). */
    assert(!is_core_module(tstate->interp, info->name, info->path));

    PyObject *mod = NULL;
    PyModuleDef *def = NULL;
    struct extensions_cache_value *cached = NULL;
    const char *name_buf = PyBytes_AS_STRING(info->name_encoded);

    /* We cannot know if the module is single-phase init or
     * multi-phase init until after we call its init function. Even
     * in isolated interpreters (that do not support single-phase init),
     * the init function will run without restriction.  For multi-phase
     * init modules that isn't a problem because the init function only
     * runs PyModuleDef_Init() on the module's def and then returns it.
     *
     * However, for single-phase init the module's init function will
     * create the module, create other objects (and allocate other
     * memory), populate it and its module state, and initialize static
     * types.  Some modules store other objects and data in global C
     * variables and register callbacks with the runtime/stdlib or
     * even external libraries (which is part of why we can't just
     * dlclose() the module in the error case).  That's a problem
     * for isolated interpreters since all of the above happens
     * and only then * will the import fail.  Memory will leak,
     * callbacks will still get used, and sometimes there
     * will be crashes (memory access violations
     * and use-after-free).
     *
     * To put it another way, if the module is single-phase init
     * then the import will probably break interpreter isolation
     * and should fail ASAP.  However, the module's init function
     * will still get run.  That means it may still store state
     * in the shared-object/DLL address space (which never gets
     * closed/cleared), including objects (e.g. static types).
     * This is a problem for isolated subinterpreters since each
     * has its own object allocator.  If the loaded shared-object
     * still holds a reference to an object after the corresponding
     * interpreter has finalized then either we must let it leak
     * or else any later use of that object by another interpreter
     * (or across multiple init-fini cycles) will crash the process.
     *
     * To avoid all of that, we make sure the module's init function
     * is always run first with the main interpreter active.  If it was
     * already the main interpreter then we can continue loading the
     * module like normal.  Otherwise, right after the init function,
     * we take care of some import state bookkeeping, switch back
     * to the subinterpreter, check for single-phase init,
     * and then continue loading like normal. */

    bool switched = false;
    /* We *could* leave in place a legacy interpreter here
     * (one that shares obmalloc/GIL with main interp),
     * but there isn't a big advantage, we anticipate
     * such interpreters will be increasingly uncommon,
     * and the code is a bit simpler if we always switch
     * to the main interpreter. */
    PyThreadState *main_tstate = switch_to_main_interpreter(tstate);
    if (main_tstate == NULL) {
        return NULL;
    }
    else if (main_tstate != tstate) {
        switched = true;
        /* In the switched case, we could play it safe
         * by getting the main interpreter's import lock here.
         * It's unlikely to matter though. */
    }

    struct _Py_ext_module_loader_result res;
    int rc = _PyImport_RunModInitFunc(p0, info, &res);
    bool main_error = false;
    if (rc < 0) {
        /* We discard res.def. */
        assert(res.module == NULL);
    }
    else {
        assert(!PyErr_Occurred());
        assert(res.err == NULL);

        mod = res.module;
        res.module = NULL;
        def = res.def;
        assert(def != NULL);

        /* Do anything else that should be done
         * while still using the main interpreter. */
        if (res.kind == _Py_ext_module_kind_SINGLEPHASE) {
            /* Remember the filename as the __file__ attribute */
            if (info->filename != NULL) {
                PyObject *filename = NULL;
                if (switched) {
                    // The original filename may be allocated by subinterpreter's
                    // obmalloc, so we create a copy here.
                    filename = _PyUnicode_Copy(info->filename);
                    if (filename == NULL) {
                        main_error = true;
                        goto main_finally;
                    }
                }
                else {
                    filename = Py_NewRef(info->filename);
                }
                // XXX There's a refleak somewhere with the filename.
                // Until we can track it down, we immortalize it.
                PyInterpreterState *interp = _PyInterpreterState_GET();
                _PyUnicode_InternImmortal(interp, &filename);

                if (PyModule_AddObjectRef(mod, "__file__", filename) < 0) {
                    PyErr_Clear(); /* Not important enough to report */
                }
            }

            /* Update global import state. */
            assert(def->m_base.m_index != 0);
            struct singlephase_global_update singlephase = {
                // XXX Modules that share a def should each get their own index,
                // whereas currently they share (which means the per-interpreter
                // cache is less reliable than it should be).
                .m_index=def->m_base.m_index,
                .origin=info->origin,
#ifdef Py_GIL_DISABLED
                .md_requires_gil=((PyModuleObject *)mod)->md_requires_gil,
#endif
            };
            // gh-88216: Extensions and def->m_base.m_copy can be updated
            // when the extension module doesn't support sub-interpreters.
            if (def->m_size == -1) {
                /* We will reload from m_copy. */
                assert(def->m_base.m_init == NULL);
                singlephase.m_dict = PyModule_GetDict(mod);
                assert(singlephase.m_dict != NULL);
            }
            else {
                /* We will reload via the init function. */
                assert(def->m_size >= 0);
                assert(def->m_base.m_copy == NULL);
                singlephase.m_init = p0;
            }
            cached = update_global_state_for_extension(
                    main_tstate, info->path, info->name, def, &singlephase);
            if (cached == NULL) {
                assert(PyErr_Occurred());
                main_error = true;
                goto main_finally;
            }
        }
    }

main_finally:
    if (rc < 0) {
        _Py_ext_module_loader_result_apply_error(&res, name_buf);
    }

    /* Switch back to the subinterpreter. */
    if (switched) {
        // gh-144601: The exception object can't be transferred across
        // interpreters. Instead, we print out an unraisable exception, and
        // then raise a different exception for the calling interpreter.
        if (rc < 0 || main_error) {
            assert(PyErr_Occurred());
            PyErr_FormatUnraisable("Exception while importing from subinterpreter");
        }
        assert(main_tstate != tstate);
        switch_back_from_main_interpreter(tstate, main_tstate, mod);
        /* Any module we got from the init function will have to be
         * reloaded in the subinterpreter. */
        mod = NULL;
        if (rc < 0 || main_error) {
            PyErr_SetString(PyExc_ImportError,
                            "failed to import from subinterpreter due to exception");
            goto error;
        }
    }

    /*****************************************************************/
    /* At this point we are back to the interpreter we started with. */
    /*****************************************************************/

    /* Finally we handle the error return from _PyImport_RunModInitFunc(). */
    if (rc < 0) {
        goto error;
    }
    if (main_error) {
        goto error;
    }

    if (res.kind == _Py_ext_module_kind_MULTIPHASE) {
        assert_multiphase_def(def);
        assert(mod == NULL);
        /* Note that we cheat a little by not repeating the calls
         * to _PyImport_GetModuleExportHooks() and _PyImport_RunModInitFunc(). */
        mod = PyModule_FromDefAndSpec(def, spec);
        if (mod == NULL) {
            goto error;
        }
    }
    else {
        assert(res.kind == _Py_ext_module_kind_SINGLEPHASE);
        assert_singlephase_def(def);

        if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) {
            goto error;
        }
        assert(!PyErr_Occurred());

        if (switched) {
            /* We switched to the main interpreter to run the init
             * function, so now we will "reload" the module from the
             * cached data using the original subinterpreter. */
            assert(mod == NULL);
            mod = reload_singlephase_extension(tstate, cached, info);
            if (mod == NULL) {
                goto error;
            }
            assert(!PyErr_Occurred());
            assert(PyModule_Check(mod));
        }
        else {
            assert(mod != NULL);
            assert(PyModule_Check(mod));

            /* Update per-interpreter import state. */
            PyObject *modules = get_modules_dict(tstate, true);
            if (finish_singlephase_extension(
                    tstate, mod, cached, info->name, modules) < 0)
            {
                goto error;
            }
        }
    }

    _Py_ext_module_loader_result_clear(&res);
    return mod;

error:
    Py_XDECREF(mod);
    _Py_ext_module_loader_result_clear(&res);
    return NULL;
}


// Used in _PyImport_ClearExtension; see notes there.
static int
clear_singlephase_extension(PyInterpreterState *interp,
                            PyObject *name, PyObject *path)
{
    struct extensions_cache_value *cached = _extensions_cache_get(path, name);
    if (cached == NULL) {
        if (PyErr_Occurred()) {
            return -1;
        }
        return 0;
    }
    PyModuleDef *def = cached->def;

    /* Clear data set when the module was initially loaded. */
    def->m_base.m_init = NULL;
    Py_CLEAR(def->m_base.m_copy);
    def->m_base.m_index = 0;

    /* Clear the PyState_*Module() cache entry. */
    Py_ssize_t index = _get_cached_module_index(cached);
    if (_modules_by_index_check(interp, index) == NULL) {
        if (_modules_by_index_clear_one(interp, index) < 0) {
            return -1;
        }
    }

    /* We must use the main interpreter to clean up the cache.
     * See the note in import_run_extension(). */
    PyThreadState *tstate = PyThreadState_GET();
    PyThreadState *main_tstate = switch_to_main_interpreter(tstate);
    if (main_tstate == NULL) {
        return -1;
    }

    /* Clear the cached module def. */
    _extensions_cache_delete(path, name);

    if (main_tstate != tstate) {
        switch_back_from_main_interpreter(tstate, main_tstate, NULL);
    }

    return 0;
}


/*******************/
/* builtin modules */
/*******************/

int
_PyImport_FixupBuiltin(PyThreadState *tstate, PyObject *mod, const char *name,
                       PyObject *modules)
{
    int res = -1;
    assert(mod != NULL && PyModule_Check(mod));

    PyObject *nameobj;
    nameobj = PyUnicode_InternFromString(name);
    if (nameobj == NULL) {
        return -1;
    }

    PyModuleDef *def = _PyModule_GetDefOrNull(mod);
    if (def == NULL) {
        assert(!PyErr_Occurred());
        PyErr_BadInternalCall();
        goto finally;
    }

    /* We only use _PyImport_FixupBuiltin() for the core builtin modules
     * (sys and builtins).  These modules are single-phase init with no
     * module state, but we also don't populate def->m_base.m_copy
     * for them. */
    assert(is_core_module(tstate->interp, nameobj, nameobj));
    assert_singlephase_def(def);
    assert(def->m_size == -1);
    assert(def->m_base.m_copy == NULL);
    assert(def->m_base.m_index >= 0);

    /* We aren't using import_find_extension() for core modules,
     * so we have to do the extra check to make sure the module
     * isn't already in the global cache before calling
     * update_global_state_for_extension(). */
    struct extensions_cache_value *cached
            = _extensions_cache_get(nameobj, nameobj);
    if (cached == NULL) {
        struct singlephase_global_update singlephase = {
            .m_index=def->m_base.m_index,
            /* We don't want def->m_base.m_copy populated. */
            .m_dict=NULL,
            .origin=_Py_ext_module_origin_CORE,
#ifdef Py_GIL_DISABLED
            /* Unused when m_dict == NULL. */
            .md_requires_gil=false,
#endif
        };
        cached = update_global_state_for_extension(
                tstate, nameobj, nameobj, def, &singlephase);
        if (cached == NULL) {
            goto finally;
        }
    }

    if (finish_singlephase_extension(tstate, mod, cached, nameobj, modules) < 0) {
        goto finally;
    }

    res = 0;

finally:
    Py_DECREF(nameobj);
    return res;
}

/* Helper to test for built-in module */

static int
is_builtin(PyObject *name)
{
    int i;
    struct _inittab *inittab = INITTAB;
    for (i = 0; inittab[i].name != NULL; i++) {
        if (_PyUnicode_EqualToASCIIString(name, inittab[i].name)) {
            if (inittab[i].initfunc == NULL)
                return -1;
            else
                return 1;
        }
    }
    return 0;
}

static struct _inittab*
lookup_inittab_entry(const struct _Py_ext_module_loader_info* info)
{
    for (struct _inittab *p = INITTAB; p->name != NULL; p++) {
        if (_PyUnicode_EqualToASCIIString(info->name, p->name)) {
            return p;
        }
    }
    // not found
    return NULL;
}

static PyObject*
create_builtin(
    PyThreadState *tstate, PyObject *name,
    PyObject *spec,
    PyModInitFunction initfunc)
{
    struct _Py_ext_module_loader_info info;
    if (_Py_ext_module_loader_info_init_for_builtin(&info, name) < 0) {
        return NULL;
    }

    struct extensions_cache_value *cached = NULL;
    PyObject *mod = import_find_extension(tstate, &info, &cached);
    if (mod != NULL) {
        assert(!_PyErr_Occurred(tstate));
        assert(cached != NULL);
        /* The module might not have md_def set in certain reload cases. */
        assert(_PyModule_GetDefOrNull(mod) == NULL
                || cached->def == _PyModule_GetDefOrNull(mod));
        assert_singlephase(cached);
        goto finally;
    }
    else if (_PyErr_Occurred(tstate)) {
        goto finally;
    }

    /* If the module was added to the global cache
     * but def->m_base.m_copy was cleared (e.g. subinterp fini)
     * then we have to do a little dance here. */
    if (cached != NULL) {
        assert(cached->def->m_base.m_copy == NULL);
        /* For now we clear the cache and move on. */
        _extensions_cache_delete(info.path, info.name);
    }

    PyModInitFunction p0 = NULL;
    if (initfunc == NULL) {
        struct _inittab *entry = lookup_inittab_entry(&info);
        if (entry == NULL) {
            mod = NULL;
            _PyErr_SetModuleNotFoundError(name);
            goto finally;
        }

        p0 = (PyModInitFunction)entry->initfunc;
    }
    else {
        p0 = initfunc;
    }

    if (p0 == NULL) {
        /* Cannot re-init internal module ("sys" or "builtins") */
        assert(is_core_module(tstate->interp, info.name, info.path));
        mod = import_add_module(tstate, info.name);
        goto finally;
    }


#ifdef Py_GIL_DISABLED
    // This call (and the corresponding call to _PyImport_CheckGILForModule())
    // would ideally be inside import_run_extension(). They are kept in the
    // callers for now because that would complicate the control flow inside
    // import_run_extension(). It should be possible to restructure
    // import_run_extension() to address this.
    _PyEval_EnableGILTransient(tstate);
#endif
    /* Now load it. */
    mod = import_run_extension(
                    tstate, p0, &info, spec, get_modules_dict(tstate, true));
#ifdef Py_GIL_DISABLED
    if (_PyImport_CheckGILForModule(mod, info.name) < 0) {
        Py_CLEAR(mod);
        goto finally;
    }
#endif

finally:
    _Py_ext_module_loader_info_clear(&info);
    return mod;
}

PyObject*
PyImport_CreateModuleFromInitfunc(
    PyObject *spec, PyObject *(*initfunc)(void))
{
    if (initfunc == NULL) {
        PyErr_BadInternalCall();
        return NULL;
    }

    PyThreadState *tstate = _PyThreadState_GET();

    PyObject *name = PyObject_GetAttr(spec, &_Py_ID(name));
    if (name == NULL) {
        return NULL;
    }

    if (!PyUnicode_Check(name)) {
        PyErr_Format(PyExc_TypeError,
                     "spec name must be string, not %T", name);
        Py_DECREF(name);
        return NULL;
    }

    PyObject *mod = create_builtin(tstate, name, spec, initfunc);
    Py_DECREF(name);
    return mod;
}

/*****************************/
/* the builtin modules table */
/*****************************/

/* API for embedding applications that want to add their own entries
   to the table of built-in modules.  This should normally be called
   *before* Py_Initialize().  When the table resize fails, -1 is
   returned and the existing table is unchanged.

   After a similar function by Just van Rossum. */

int
PyImport_ExtendInittab(struct _inittab *newtab)
{
    struct _inittab *p;
    size_t i, n;
    int res = 0;

    if (INITTAB != NULL) {
        Py_FatalError("PyImport_ExtendInittab() may not be called after Py_Initialize()");
    }

    /* Count the number of entries in both tables */
    for (n = 0; newtab[n].name != NULL; n++)
        ;
    if (n == 0)
        return 0; /* Nothing to do */
    for (i = 0; PyImport_Inittab[i].name != NULL; i++)
        ;

    /* Force default raw memory allocator to get a known allocator to be able
       to release the memory in _PyImport_Fini2() */
    /* Allocate new memory for the combined table */
    p = NULL;
    if (i + n <= SIZE_MAX / sizeof(struct _inittab) - 1) {
        size_t size = sizeof(struct _inittab) * (i + n + 1);
        p = _PyMem_DefaultRawRealloc(inittab_copy, size);
    }
    if (p == NULL) {
        res = -1;
        goto done;
    }

    /* Copy the tables into the new memory at the first call
       to PyImport_ExtendInittab(). */
    if (inittab_copy != PyImport_Inittab) {
        memcpy(p, PyImport_Inittab, (i+1) * sizeof(struct _inittab));
    }
    memcpy(p + i, newtab, (n + 1) * sizeof(struct _inittab));
    PyImport_Inittab = inittab_copy = p;
done:
    return res;
}

/* Shorthand to add a single entry given a name and a function */

int
PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void))
{
    struct _inittab newtab[2];

    if (INITTAB != NULL) {
        Py_FatalError("PyImport_AppendInittab() may not be called after Py_Initialize()");
    }

    memset(newtab, '\0', sizeof newtab);

    newtab[0].name = name;
    newtab[0].initfunc = initfunc;

    return PyImport_ExtendInittab(newtab);
}


/* the internal table */

static int
init_builtin_modules_table(void)
{
    size_t size;
    for (size = 0; PyImport_Inittab[size].name != NULL; size++)
        ;
    size++;

    /* Make the copy. */
    struct _inittab *copied = _PyMem_DefaultRawMalloc(size * sizeof(struct _inittab));
    if (copied == NULL) {
        return -1;
    }
    memcpy(copied, PyImport_Inittab, size * sizeof(struct _inittab));
    INITTAB = copied;
    return 0;
}

static void
fini_builtin_modules_table(void)
{
    struct _inittab *inittab = INITTAB;
    INITTAB = NULL;
    _PyMem_DefaultRawFree(inittab);
}

PyObject *
_PyImport_GetBuiltinModuleNames(void)
{
    PyObject *list = PyList_New(0);
    if (list == NULL) {
        return NULL;
    }
    struct _inittab *inittab = INITTAB;
    for (Py_ssize_t i = 0; inittab[i].name != NULL; i++) {
        PyObject *name = PyUnicode_FromString(inittab[i].name);
        if (name == NULL) {
            Py_DECREF(list);
            return NULL;
        }
        if (PyList_Append(list, name) < 0) {
            Py_DECREF(name);
            Py_DECREF(list);
            return NULL;
        }
        Py_DECREF(name);
    }
    return list;
}


/********************/
/* the magic number */
/********************/

/* Helper for pythonrun.c -- return magic number and tag. */

long
PyImport_GetMagicNumber(void)
{
    return PYC_MAGIC_NUMBER_TOKEN;
}

extern const char * _PySys_ImplCacheTag;

const char *
PyImport_GetMagicTag(void)
{
    return _PySys_ImplCacheTag;
}


/*********************************/
/* a Python module's code object */
/*********************************/

/* Execute a code object in a module and return the module object
 * WITH INCREMENTED REFERENCE COUNT.  If an error occurs, name is
 * removed from sys.modules, to avoid leaving damaged module objects
 * in sys.modules.  The caller may wish to restore the original
 * module object (if any) in this case; PyImport_ReloadModule is an
 * example.
 *
 * Note that PyImport_ExecCodeModuleWithPathnames() is the preferred, richer
 * interface.  The other two exist primarily for backward compatibility.
 */
PyObject *
PyImport_ExecCodeModule(const char *name, PyObject *co)
{
    return PyImport_ExecCodeModuleWithPathnames(
        name, co, (char *)NULL, (char *)NULL);
}

PyObject *
PyImport_ExecCodeModuleEx(const char *name, PyObject *co, const char *pathname)
{
    return PyImport_ExecCodeModuleWithPathnames(
        name, co, pathname, (char *)NULL);
}

PyObject *
PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co,
                                     const char *pathname,
                                     const char *cpathname)
{
    PyObject *m = NULL;
    PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL, *external= NULL;

    nameobj = PyUnicode_FromString(name);
    if (nameobj == NULL)
        return NULL;

    if (cpathname != NULL) {
        cpathobj = PyUnicode_DecodeFSDefault(cpathname);
        if (cpathobj == NULL)
            goto error;
    }
    else
        cpathobj = NULL;

    if (pathname != NULL) {
        pathobj = PyUnicode_DecodeFSDefault(pathname);
        if (pathobj == NULL)
            goto error;
    }
    else if (cpathobj != NULL) {
        PyInterpreterState *interp = _PyInterpreterState_GET();

        if (interp == NULL) {
            Py_FatalError("no current interpreter");
        }

        external= PyObject_GetAttrString(IMPORTLIB(interp),
                                         "_bootstrap_external");
        if (external != NULL) {
            pathobj = PyObject_CallMethodOneArg(
                external, &_Py_ID(_get_sourcefile), cpathobj);
            Py_DECREF(external);
        }
        if (pathobj == NULL)
            PyErr_Clear();
    }
    else
        pathobj = NULL;

    m = PyImport_ExecCodeModuleObject(nameobj, co, pathobj, cpathobj);
error:
    Py_DECREF(nameobj);
    Py_XDECREF(pathobj);
    Py_XDECREF(cpathobj);
    return m;
}

static PyObject *
module_dict_for_exec(PyThreadState *tstate, PyObject *name)
{
    PyObject *m, *d;

    m = import_add_module(tstate, name);
    if (m == NULL)
        return NULL;
    /* If the module is being reloaded, we get the old module back
       and re-use its dict to exec the new code. */
    d = PyModule_GetDict(m);
    int r = PyDict_Contains(d, &_Py_ID(__builtins__));
    if (r == 0) {
        r = PyDict_SetItem(d, &_Py_ID(__builtins__), PyEval_GetBuiltins());
    }
    if (r < 0) {
        remove_module(tstate, name);
        Py_DECREF(m);
        return NULL;
    }

    Py_INCREF(d);
    Py_DECREF(m);
    return d;
}

static PyObject *
exec_code_in_module(PyThreadState *tstate, PyObject *name,
                    PyObject *module_dict, PyObject *code_object)
{
    PyObject *v, *m;

    v = PyEval_EvalCode(code_object, module_dict, module_dict);
    if (v == NULL) {
        remove_module(tstate, name);
        return NULL;
    }
    Py_DECREF(v);

    m = import_get_module(tstate, name);
    if (m == NULL && !_PyErr_Occurred(tstate)) {
        _PyErr_Format(tstate, PyExc_ImportError,
                      "Loaded module %R not found in sys.modules",
                      name);
    }

    return m;
}

PyObject*
PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
                              PyObject *cpathname)
{
    PyThreadState *tstate = _PyThreadState_GET();
    PyObject *d, *external, *res;

    d = module_dict_for_exec(tstate, name);
    if (d == NULL) {
        return NULL;
    }

    if (pathname == NULL) {
        pathname = ((PyCodeObject *)co)->co_filename;
    }
    external = PyObject_GetAttrString(IMPORTLIB(tstate->interp),
                                      "_bootstrap_external");
    if (external == NULL) {
        Py_DECREF(d);
        return NULL;
    }
    res = PyObject_CallMethodObjArgs(external, &_Py_ID(_fix_up_module),
                                     d, name, pathname, cpathname, NULL);
    Py_DECREF(external);
    if (res != NULL) {
        Py_DECREF(res);
        res = exec_code_in_module(tstate, name, d, co);
    }
    Py_DECREF(d);
    return res;
}


static void
update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname)
{
    PyObject *constants, *tmp;
    Py_ssize_t i, n;

    if (PyUnicode_Compare(co->co_filename, oldname))
        return;

    Py_XSETREF(co->co_filename, Py_NewRef(newname));

    constants = co->co_consts;
    n = PyTuple_GET_SIZE(constants);
    for (i = 0; i < n; i++) {
        tmp = PyTuple_GET_ITEM(constants, i);
        if (PyCode_Check(tmp))
            update_code_filenames((PyCodeObject *)tmp,
                                  oldname, newname);
    }
}

static void
update_compiled_module(PyCodeObject *co, PyObject *newname)
{
    PyObject *oldname;

    if (PyUnicode_Compare(co->co_filename, newname) == 0)
        return;

    oldname = co->co_filename;
    Py_INCREF(oldname);
    update_code_filenames(co, oldname, newname);
    Py_DECREF(oldname);
}


/******************/
/* frozen modules */
/******************/

/* Return true if the name is an alias.  In that case, "alias" is set
   to the original module name.  If it is an alias but the original
   module isn't known then "alias" is set to NULL while true is returned. */
static bool
resolve_module_alias(const char *name, const struct _module_alias *aliases,
                     const char **alias)
{
    const struct _module_alias *entry;
    for (entry = aliases; ; entry++) {
        if (entry->name == NULL) {
            /* It isn't an alias. */
            return false;
        }
        if (strcmp(name, entry->name) == 0) {
            if (alias != NULL) {
                *alias = entry->orig;
            }
            return true;
        }
    }
}

static bool
use_frozen(void)
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    int override = OVERRIDE_FROZEN_MODULES(interp);
    if (override > 0) {
        return true;
    }
    else if (override < 0) {
        return false;
    }
    else {
        return interp->config.use_frozen_modules;
    }
}

static PyObject *
list_frozen_module_names(void)
{
    PyObject *names = PyList_New(0);
    if (names == NULL) {
        return NULL;
    }
    bool enabled = use_frozen();
    const struct _frozen *p;
#define ADD_MODULE(name) \
    do { \
        PyObject *nameobj = PyUnicode_FromString(name); \
        if (nameobj == NULL) { \
            goto error; \
        } \
        int res = PyList_Append(names, nameobj); \
        Py_DECREF(nameobj); \
        if (res != 0) { \
            goto error; \
        } \
    } while(0)
    // We always use the bootstrap modules.
    for (p = _PyImport_FrozenBootstrap; ; p++) {
        if (p->name == NULL) {
            break;
        }
        ADD_MODULE(p->name);
    }
    // Frozen stdlib modules may be disabled.
    for (p = _PyImport_FrozenStdlib; ; p++) {
        if (p->name == NULL) {
            break;
        }
        if (enabled) {
            ADD_MODULE(p->name);
        }
    }
    for (p = _PyImport_FrozenTest; ; p++) {
        if (p->name == NULL) {
            break;
        }
        if (enabled) {
            ADD_MODULE(p->name);
        }
    }
#undef ADD_MODULE
    // Add any custom modules.
    if (PyImport_FrozenModules != NULL) {
        for (p = PyImport_FrozenModules; ; p++) {
            if (p->name == NULL) {
                break;
            }
            PyObject *nameobj = PyUnicode_FromString(p->name);
            if (nameobj == NULL) {
                goto error;
            }
            int found = PySequence_Contains(names, nameobj);
            if (found < 0) {
                Py_DECREF(nameobj);
                goto error;
            }
            else if (found) {
                Py_DECREF(nameobj);
            }
            else {
                int res = PyList_Append(names, nameobj);
                Py_DECREF(nameobj);
                if (res != 0) {
                    goto error;
                }
            }
        }
    }
    return names;

error:
    Py_DECREF(names);
    return NULL;
}

typedef enum {
    FROZEN_OKAY,
    FROZEN_BAD_NAME,    // The given module name wasn't valid.
    FROZEN_NOT_FOUND,   // It wasn't in PyImport_FrozenModules.
    FROZEN_DISABLED,    // -X frozen_modules=off (and not essential)
    FROZEN_EXCLUDED,    /* The PyImport_FrozenModules entry has NULL "code"
                           (module is present but marked as unimportable, stops search). */
    FROZEN_INVALID,     /* The PyImport_FrozenModules entry is bogus
                           (eg. does not contain executable code). */
} frozen_status;

static inline void
set_frozen_error(frozen_status status, PyObject *modname)
{
    const char *err = NULL;
    switch (status) {
        case FROZEN_BAD_NAME:
        case FROZEN_NOT_FOUND:
            err = "No such frozen object named %R";
            break;
        case FROZEN_DISABLED:
            err = "Frozen modules are disabled and the frozen object named %R is not essential";
            break;
        case FROZEN_EXCLUDED:
            err = "Excluded frozen object named %R";
            break;
        case FROZEN_INVALID:
            err = "Frozen object named %R is invalid";
            break;
        case FROZEN_OKAY:
            // There was no error.
            break;
        default:
            Py_UNREACHABLE();
    }
    if (err != NULL) {
        PyObject *msg = PyUnicode_FromFormat(err, modname);
        if (msg == NULL) {
            PyErr_Clear();
        }
        PyErr_SetImportError(msg, modname, NULL);
        Py_XDECREF(msg);
    }
}

static const struct _frozen *
look_up_frozen(const char *name)
{
    const struct _frozen *p;
    // We always use the bootstrap modules.
    for (p = _PyImport_FrozenBootstrap; ; p++) {
        if (p->name == NULL) {
            // We hit the end-of-list sentinel value.
            break;
        }
        if (strcmp(name, p->name) == 0) {
            return p;
        }
    }
    // Prefer custom modules, if any.  Frozen stdlib modules can be
    // disabled here by setting "code" to NULL in the array entry.
    if (PyImport_FrozenModules != NULL) {
        for (p = PyImport_FrozenModules; ; p++) {
            if (p->name == NULL) {
                break;
            }
            if (strcmp(name, p->name) == 0) {
                return p;
            }
        }
    }
    // Frozen stdlib modules may be disabled.
    if (use_frozen()) {
        for (p = _PyImport_FrozenStdlib; ; p++) {
            if (p->name == NULL) {
                break;
            }
            if (strcmp(name, p->name) == 0) {
                return p;
            }
        }
        for (p = _PyImport_FrozenTest; ; p++) {
            if (p->name == NULL) {
                break;
            }
            if (strcmp(name, p->name) == 0) {
                return p;
            }
        }
    }
    return NULL;
}

struct frozen_info {
    PyObject *nameobj;
    const char *data;
    Py_ssize_t size;
    bool is_package;
    bool is_alias;
    const char *origname;
};

static frozen_status
find_frozen(PyObject *nameobj, struct frozen_info *info)
{
    if (info != NULL) {
        memset(info, 0, sizeof(*info));
    }

    if (nameobj == NULL || nameobj == Py_None) {
        return FROZEN_BAD_NAME;
    }
    const char *name = _PyUnicode_AsUTF8NoNUL(nameobj);
    if (name == NULL) {
        // Note that this function previously used
        // _PyUnicode_EqualToASCIIString().  We clear the error here
        // (instead of propagating it) to match the earlier behavior
        // more closely.
        PyErr_Clear();
        return FROZEN_BAD_NAME;
    }

    const struct _frozen *p = look_up_frozen(name);
    if (p == NULL) {
        return FROZEN_NOT_FOUND;
    }
    if (info != NULL) {
        info->nameobj = nameobj;  // borrowed
        info->data = (const char *)p->code;
        info->size = p->size;
        info->is_package = p->is_package;
        if (p->size < 0) {
            // backward compatibility with negative size values
            info->size = -(p->size);
            info->is_package = true;
        }
        info->origname = name;
        info->is_alias = resolve_module_alias(name, _PyImport_FrozenAliases,
                                              &info->origname);
    }
    if (p->code == NULL) {
        /* It is frozen but marked as un-importable. */
        return FROZEN_EXCLUDED;
    }
    if (p->code[0] == '\0' || p->size == 0) {
        /* Does not contain executable code. */
        return FROZEN_INVALID;
    }
    return FROZEN_OKAY;
}

static PyObject *
unmarshal_frozen_code(PyInterpreterState *interp, struct frozen_info *info)
{
    PyObject *co = PyMarshal_ReadObjectFromString(info->data, info->size);
    if (co == NULL) {
        /* Does not contain executable code. */
        PyErr_Clear();
        set_frozen_error(FROZEN_INVALID, info->nameobj);
        return NULL;
    }
    if (!PyCode_Check(co)) {
        // We stick with TypeError for backward compatibility.
        PyErr_Format(PyExc_TypeError,
                     "frozen object %R is not a code object",
                     info->nameobj);
        Py_DECREF(co);
        return NULL;
    }
    return co;
}


/* Initialize a frozen module.
   Return 1 for success, 0 if the module is not found, and -1 with
   an exception set if the initialization failed.
   This function is also used from frozenmain.c */

int
PyImport_ImportFrozenModuleObject(PyObject *name)
{
    PyThreadState *tstate = _PyThreadState_GET();
    PyObject *co, *m, *d = NULL;
    int err;

    struct frozen_info info;
    frozen_status status = find_frozen(name, &info);
    if (status == FROZEN_NOT_FOUND || status == FROZEN_DISABLED) {
        return 0;
    }
    else if (status == FROZEN_BAD_NAME) {
        return 0;
    }
    else if (status != FROZEN_OKAY) {
        set_frozen_error(status, name);
        return -1;
    }
    co = unmarshal_frozen_code(tstate->interp, &info);
    if (co == NULL) {
        return -1;
    }
    if (info.is_package) {
        /* Set __path__ to the empty list */
        PyObject *l;
        m = import_add_module(tstate, name);
        if (m == NULL)
            goto err_return;
        d = PyModule_GetDict(m);
        l = PyList_New(0);
        if (l == NULL) {
            Py_DECREF(m);
            goto err_return;
        }
        err = PyDict_SetItemString(d, "__path__", l);
        Py_DECREF(l);
        Py_DECREF(m);
        if (err != 0)
            goto err_return;
    }
    d = module_dict_for_exec(tstate, name);
    if (d == NULL) {
        goto err_return;
    }
    m = exec_code_in_module(tstate, name, d, co);
    if (m == NULL) {
        goto err_return;
    }
    Py_DECREF(m);
    /* Set __origname__ (consumed in FrozenImporter._setup_module()). */
    PyObject *origname;
    if (info.origname) {
        origname = PyUnicode_FromString(info.origname);
        if (origname == NULL) {
            goto err_return;
        }
    }
    else {
        origname = Py_NewRef(Py_None);
    }
    err = PyDict_SetItemString(d, "__origname__", origname);
    Py_DECREF(origname);
    if (err != 0) {
        goto err_return;
    }
    Py_DECREF(d);
    Py_DECREF(co);
    return 1;

err_return:
    Py_XDECREF(d);
    Py_DECREF(co);
    return -1;
}

int
PyImport_ImportFrozenModule(const char *name)
{
    PyObject *nameobj;
    int ret;
    nameobj = PyUnicode_InternFromString(name);
    if (nameobj == NULL)
        return -1;
    ret = PyImport_ImportFrozenModuleObject(nameobj);
    Py_DECREF(nameobj);
    return ret;
}


/*************/
/* importlib */
/*************/

/* Import the _imp extension by calling manually _imp.create_builtin() and
   _imp.exec_builtin() since importlib is not initialized yet. Initializing
   importlib requires the _imp module: this function fix the bootstrap issue.
 */
static PyObject*
bootstrap_imp(PyThreadState *tstate)
{
    PyObject *name = PyUnicode_FromString("_imp");
    if (name == NULL) {
        return NULL;
    }

    // Mock a ModuleSpec object just good enough for PyModule_FromDefAndSpec():
    // an object with just a name attribute.
    //
    // _imp.__spec__ is overridden by importlib._bootstrap._instal() anyway.
    PyObject *attrs = Py_BuildValue("{sO}", "name", name);
    if (attrs == NULL) {
        goto error;
    }
    PyObject *spec = _PyNamespace_New(attrs);
    Py_DECREF(attrs);
    if (spec == NULL) {
        goto error;
    }

    // Create the _imp module from its definition.
    PyObject *mod = create_builtin(tstate, name, spec, NULL);
    Py_CLEAR(name);
    Py_DECREF(spec);
    if (mod == NULL) {
        goto error;
    }
    assert(mod != Py_None);  // not found

    // Execute the _imp module: call imp_module_exec().
    if (exec_builtin_or_dynamic(mod) < 0) {
        Py_DECREF(mod);
        goto error;
    }
    return mod;

error:
    Py_XDECREF(name);
    return NULL;
}

/* Global initializations.  Can be undone by Py_FinalizeEx().  Don't
   call this twice without an intervening Py_FinalizeEx() call.  When
   initializations fail, a fatal error is issued and the function does
   not return.  On return, the first thread and interpreter state have
   been created.

   Locking: you must hold the interpreter lock while calling this.
   (If the lock has not yet been initialized, that's equivalent to
   having the lock, but you cannot use multiple threads.)

*/
static int
init_importlib(PyThreadState *tstate, PyObject *sysmod)
{
    assert(!_PyErr_Occurred(tstate));

    PyInterpreterState *interp = tstate->interp;
    int verbose = _PyInterpreterState_GetConfig(interp)->verbose;

    // Import _importlib through its frozen version, _frozen_importlib.
    if (verbose) {
        PySys_FormatStderr("import _frozen_importlib # frozen\n");
    }
    if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) {
        return -1;
    }

    PyObject *importlib = PyImport_AddModuleRef("_frozen_importlib");
    if (importlib == NULL) {
        return -1;
    }
    IMPORTLIB(interp) = importlib;

    // Import the _imp module
    if (verbose) {
        PySys_FormatStderr("import _imp # builtin\n");
    }
    PyObject *imp_mod = bootstrap_imp(tstate);
    if (imp_mod == NULL) {
        return -1;
    }
    if (_PyImport_SetModuleString("_imp", imp_mod) < 0) {
        Py_DECREF(imp_mod);
        return -1;
    }

    // Install importlib as the implementation of import
    PyObject *value = PyObject_CallMethod(importlib, "_install",
                                          "OO", sysmod, imp_mod);
    Py_DECREF(imp_mod);
    if (value == NULL) {
        return -1;
    }
    Py_DECREF(value);

    assert(!_PyErr_Occurred(tstate));
    return 0;
}


static int
init_importlib_external(PyInterpreterState *interp)
{
    PyObject *value;
    value = PyObject_CallMethod(IMPORTLIB(interp),
                                "_install_external_importers", "");
    if (value == NULL) {
        return -1;
    }
    Py_DECREF(value);
    return 0;
}

PyObject *
_PyImport_GetImportlibLoader(PyInterpreterState *interp,
                             const char *loader_name)
{
    return PyObject_GetAttrString(IMPORTLIB(interp), loader_name);
}

PyObject *
_PyImport_GetImportlibExternalLoader(PyInterpreterState *interp,
                                     const char *loader_name)
{
    PyObject *bootstrap = PyObject_GetAttrString(IMPORTLIB(interp),
                                                 "_bootstrap_external");
    if (bootstrap == NULL) {
        return NULL;
    }

    PyObject *loader_type = PyObject_GetAttrString(bootstrap, loader_name);
    Py_DECREF(bootstrap);
    return loader_type;
}

PyObject *
_PyImport_BlessMyLoader(PyInterpreterState *interp, PyObject *module_globals)
{
    PyObject *external = PyObject_GetAttrString(IMPORTLIB(interp),
                                                "_bootstrap_external");
    if (external == NULL) {
        return NULL;
    }

    PyObject *loader = PyObject_CallMethod(external, "_bless_my_loader",
                                           "O", module_globals, NULL);
    Py_DECREF(external);
    return loader;
}

PyObject *
_PyImport_ImportlibModuleRepr(PyInterpreterState *interp, PyObject *m)
{
    return PyObject_CallMethod(IMPORTLIB(interp), "_module_repr", "O", m);
}


/*******************/

/* Return a finder object for a sys.path/pkg.__path__ item 'p',
   possibly by fetching it from the path_importer_cache dict. If it
   wasn't yet cached, traverse path_hooks until a hook is found
   that can handle the path item. Return None if no hook could;
   this tells our caller that the path based finder could not find
   a finder for this path item. Cache the result in
   path_importer_cache. */

static PyObject *
get_path_importer(PyThreadState *tstate, PyObject *path_importer_cache,
                  PyObject *path_hooks, PyObject *p)
{
    PyObject *importer;
    Py_ssize_t j, nhooks;

    if (!PyList_Check(path_hooks)) {
        PyErr_SetString(PyExc_RuntimeError, "sys.path_hooks is not a list");
        return NULL;
    }
    if (!PyDict_Check(path_importer_cache)) {
        PyErr_SetString(PyExc_RuntimeError, "sys.path_importer_cache is not a dict");
        return NULL;
    }

    nhooks = PyList_Size(path_hooks);
    if (nhooks < 0)
        return NULL; /* Shouldn't happen */

    if (PyDict_GetItemRef(path_importer_cache, p, &importer) != 0) {
        // found or error
        return importer;
    }
    // not found
    /* set path_importer_cache[p] to None to avoid recursion */
    if (PyDict_SetItem(path_importer_cache, p, Py_None) != 0)
        return NULL;

    for (j = 0; j < nhooks; j++) {
        PyObject *hook = PyList_GetItem(path_hooks, j);
        if (hook == NULL)
            return NULL;
        importer = PyObject_CallOneArg(hook, p);
        if (importer != NULL)
            break;

        if (!_PyErr_ExceptionMatches(tstate, PyExc_ImportError)) {
            return NULL;
        }
        _PyErr_Clear(tstate);
    }
    if (importer == NULL) {
        Py_RETURN_NONE;
    }
    if (PyDict_SetItem(path_importer_cache, p, importer) < 0) {
        Py_DECREF(importer);
        return NULL;
    }
    return importer;
}

PyObject *
PyImport_GetImporter(PyObject *path)
{
    PyThreadState *tstate = _PyThreadState_GET();
    PyObject *path_importer_cache = PySys_GetAttrString("path_importer_cache");
    if (path_importer_cache == NULL) {
        return NULL;
    }
    PyObject *path_hooks = PySys_GetAttrString("path_hooks");
    if (path_hooks == NULL) {
        Py_DECREF(path_importer_cache);
        return NULL;
    }
    PyObject *importer = get_path_importer(tstate, path_importer_cache, path_hooks, path);
    Py_DECREF(path_hooks);
    Py_DECREF(path_importer_cache);
    return importer;
}


/*********************/
/* importing modules */
/*********************/

int
_PyImport_InitDefaultImportFunc(PyInterpreterState *interp)
{
    // Get the __import__ function
    PyObject *import_func;
    if (PyDict_GetItemStringRef(interp->builtins, "__import__", &import_func) <= 0) {
        return -1;
    }
    IMPORT_FUNC(interp) = import_func;

    // Get the __lazy_import__ function
    if (PyDict_GetItemStringRef(interp->builtins, "__lazy_import__",
                                &import_func) <= 0) {
        return -1;
    }
    LAZY_IMPORT_FUNC(interp) = import_func;
    return 0;
}

int
_PyImport_IsDefaultImportFunc(PyInterpreterState *interp, PyObject *func)
{
    return func == IMPORT_FUNC(interp);
}

int
_PyImport_IsDefaultLazyImportFunc(PyInterpreterState *interp, PyObject *func)
{
    return func == LAZY_IMPORT_FUNC(interp);
}

/* Import a module, either built-in, frozen, or external, and return
   its module object WITH INCREMENTED REFERENCE COUNT */

PyObject *
PyImport_ImportModule(const char *name)
{
    PyObject *pname;
    PyObject *result;

    pname = PyUnicode_FromString(name);
    if (pname == NULL)
        return NULL;
    result = PyImport_Import(pname);
    Py_DECREF(pname);
    return result;
}


/* Import a module without blocking
 *
 * At first it tries to fetch the module from sys.modules. If the module was
 * never loaded before it loads it with PyImport_ImportModule() unless another
 * thread holds the import lock. In the latter case the function raises an
 * ImportError instead of blocking.
 *
 * Returns the module object with incremented ref count.
 *
 * Removed in 3.15, but kept for stable ABI compatibility.
 */
PyAPI_FUNC(PyObject *)
PyImport_ImportModuleNoBlock(const char *name)
{
    if (PyErr_WarnEx(PyExc_DeprecationWarning,
        "PyImport_ImportModuleNoBlock() is deprecated and scheduled for "
        "removal in Python 3.15. Use PyImport_ImportModule() instead.", 1))
    {
        return NULL;
    }
    return PyImport_ImportModule(name);
}


/* Remove importlib frames from the traceback,
 * except in Verbose mode. */
static void
remove_importlib_frames(PyThreadState *tstate)
{
    const char *importlib_filename = "<frozen importlib._bootstrap>";
    const char *external_filename = "<frozen importlib._bootstrap_external>";
    const char *remove_frames = "_call_with_frames_removed";
    int always_trim = 0;
    int in_importlib = 0;
    PyObject **prev_link, **outer_link = NULL;
    PyObject *base_tb = NULL;

    /* Synopsis: if it's an ImportError, we trim all importlib chunks
       from the traceback. We always trim chunks
       which end with a call to "_call_with_frames_removed". */

    PyObject *exc = _PyErr_GetRaisedException(tstate);
    if (exc == NULL || _PyInterpreterState_GetConfig(tstate->interp)->verbose) {
        goto done;
    }

    if (PyType_IsSubtype(Py_TYPE(exc), (PyTypeObject *) PyExc_ImportError)) {
        always_trim = 1;
    }

    assert(PyExceptionInstance_Check(exc));
    base_tb = PyException_GetTraceback(exc);
    prev_link = &base_tb;
    PyObject *tb = base_tb;
    while (tb != NULL) {
        assert(PyTraceBack_Check(tb));
        PyTracebackObject *traceback = (PyTracebackObject *)tb;
        PyObject *next = (PyObject *) traceback->tb_next;
        PyFrameObject *frame = traceback->tb_frame;
        PyCodeObject *code = PyFrame_GetCode(frame);
        int now_in_importlib;

        now_in_importlib = _PyUnicode_EqualToASCIIString(code->co_filename, importlib_filename) ||
                           _PyUnicode_EqualToASCIIString(code->co_filename, external_filename);
        if (now_in_importlib && !in_importlib) {
            /* This is the link to this chunk of importlib tracebacks */
            outer_link = prev_link;
        }
        in_importlib = now_in_importlib;

        if (in_importlib &&
            (always_trim ||
             _PyUnicode_EqualToASCIIString(code->co_name, remove_frames))) {
            Py_XSETREF(*outer_link, Py_XNewRef(next));
            prev_link = outer_link;
        }
        else {
            prev_link = (PyObject **) &traceback->tb_next;
        }
        Py_DECREF(code);
        tb = next;
    }
    if (base_tb == NULL) {
        base_tb = Py_None;
        Py_INCREF(Py_None);
    }
    PyException_SetTraceback(exc, base_tb);
done:
    Py_XDECREF(base_tb);
    _PyErr_SetRaisedException(tstate, exc);
}


static PyObject *
resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level)
{
    PyObject *abs_name;
    PyObject *package = NULL;
    PyObject *spec = NULL;
    Py_ssize_t last_dot;
    PyObject *base;
    int level_up;

    if (globals == NULL) {
        _PyErr_SetString(tstate, PyExc_KeyError, "'__name__' not in globals");
        goto error;
    }
    if (!PyAnyDict_Check(globals)) {
        _PyErr_SetString(tstate, PyExc_TypeError,
                         "globals must be a dict or a frozendict");
        goto error;
    }
    if (PyDict_GetItemRef(globals, &_Py_ID(__package__), &package) < 0) {
        goto error;
    }
    if (package == Py_None) {
        Py_DECREF(package);
        package = NULL;
    }
    if (PyDict_GetItemRef(globals, &_Py_ID(__spec__), &spec) < 0) {
        goto error;
    }

    if (package != NULL) {
        if (!PyUnicode_Check(package)) {
            _PyErr_SetString(tstate, PyExc_TypeError,
                             "package must be a string");
            goto error;
        }
        else if (spec != NULL && spec != Py_None) {
            int equal;
            PyObject *parent = PyObject_GetAttr(spec, &_Py_ID(parent));
            if (parent == NULL) {
                goto error;
            }

            equal = PyObject_RichCompareBool(package, parent, Py_EQ);
            Py_DECREF(parent);
            if (equal < 0) {
                goto error;
            }
            else if (equal == 0) {
                if (PyErr_WarnEx(PyExc_DeprecationWarning,
                        "__package__ != __spec__.parent", 1) < 0) {
                    goto error;
                }
            }
        }
    }
    else if (spec != NULL && spec != Py_None) {
        package = PyObject_GetAttr(spec, &_Py_ID(parent));
        if (package == NULL) {
            goto error;
        }
        else if (!PyUnicode_Check(package)) {
            _PyErr_SetString(tstate, PyExc_TypeError,
                             "__spec__.parent must be a string");
            goto error;
        }
    }
    else {
        if (PyErr_WarnEx(PyExc_ImportWarning,
                    "can't resolve package from __spec__ or __package__, "
                    "falling back on __name__ and __path__", 1) < 0) {
            goto error;
        }

        if (PyDict_GetItemRef(globals, &_Py_ID(__name__), &package) < 0) {
            goto error;
        }
        if (package == NULL) {
            _PyErr_SetString(tstate, PyExc_KeyError,
                             "'__name__' not in globals");
            goto error;
        }

        if (!PyUnicode_Check(package)) {
            _PyErr_SetString(tstate, PyExc_TypeError,
                             "__name__ must be a string");
            goto error;
        }

        int haspath = PyDict_Contains(globals, &_Py_ID(__path__));
        if (haspath < 0) {
            goto error;
        }
        if (!haspath) {
            Py_ssize_t dot;

            dot = PyUnicode_FindChar(package, '.',
                                        0, PyUnicode_GET_LENGTH(package), -1);
            if (dot == -2) {
                goto error;
            }
            else if (dot == -1) {
                goto no_parent_error;
            }
            PyObject *substr = PyUnicode_Substring(package, 0, dot);
            if (substr == NULL) {
                goto error;
            }
            Py_SETREF(package, substr);
        }
    }

    last_dot = PyUnicode_GET_LENGTH(package);
    if (last_dot == 0) {
        goto no_parent_error;
    }

    for (level_up = 1; level_up < level; level_up += 1) {
        last_dot = PyUnicode_FindChar(package, '.', 0, last_dot, -1);
        if (last_dot == -2) {
            goto error;
        }
        else if (last_dot == -1) {
            _PyErr_SetString(tstate, PyExc_ImportError,
                             "attempted relative import beyond top-level "
                             "package");
            goto error;
        }
    }

    Py_XDECREF(spec);
    base = PyUnicode_Substring(package, 0, last_dot);
    Py_DECREF(package);
    if (base == NULL || PyUnicode_GET_LENGTH(name) == 0) {
        return base;
    }

    abs_name = PyUnicode_FromFormat("%U.%U", base, name);
    Py_DECREF(base);
    return abs_name;

  no_parent_error:
    _PyErr_SetString(tstate, PyExc_ImportError,
                     "attempted relative import "
                     "with no known parent package");

  error:
    Py_XDECREF(spec);
    Py_XDECREF(package);
    return NULL;
}

PyObject *
_PyImport_ResolveName(PyThreadState *tstate, PyObject *name,
                      PyObject *globals, int level)
{
  return resolve_name(tstate, name, globals, level);
}

PyObject *
_PyImport_LoadLazyImportTstate(PyThreadState *tstate, PyObject *lazy_import)
{
    PyObject *obj = NULL;
    PyObject *fromlist = Py_None;
    PyObject *import_func = NULL;
    assert(lazy_import != NULL);
    assert(PyLazyImport_CheckExact(lazy_import));

    PyLazyImportObject *lz = (PyLazyImportObject *)lazy_import;
    PyInterpreterState *interp = tstate->interp;

    // Acquire the global import lock to serialize reification
    _PyImport_AcquireLock(interp);

    // Check if we are already importing this module, if so, then we want to
    // return an error that indicates we've hit a cycle which will indicate
    // the value isn't yet available.
    PyObject *importing = interp->imports.lazy_importing_modules;
    if (importing == NULL) {
        importing = interp->imports.lazy_importing_modules = PySet_New(NULL);
        if (importing == NULL) {
            _PyImport_ReleaseLock(interp);
            return NULL;
        }
    }

    assert(PyAnySet_CheckExact(importing));
    int is_loading = _PySet_Contains((PySetObject *)importing, lazy_import);
    if (is_loading < 0) {
        _PyImport_ReleaseLock(interp);
        return NULL;
    }
    else if (is_loading == 1) {
        PyObject *name = _PyLazyImport_GetName(lazy_import);
        if (name == NULL) {
            _PyImport_ReleaseLock(interp);
            return NULL;
        }
        PyObject *errmsg = PyUnicode_FromFormat(
            "cannot import name %R (most likely due to a circular import)",
            name);
        if (errmsg == NULL) {
            Py_DECREF(name);
            _PyImport_ReleaseLock(interp);
            return NULL;
        }
        PyErr_SetImportErrorSubclass(PyExc_ImportCycleError, errmsg,
                                     lz->lz_from, NULL);
        Py_DECREF(errmsg);
        Py_DECREF(name);
        _PyImport_ReleaseLock(interp);
        return NULL;
    }
    else if (PySet_Add(importing, lazy_import) < 0) {
        goto error;
    }

    Py_ssize_t dot = -1;
    int full = 0;
    if (lz->lz_attr != NULL) {
        full = 1;
    }
    if (!full) {
        dot = PyUnicode_FindChar(lz->lz_from, '.', 0,
                                 PyUnicode_GET_LENGTH(lz->lz_from), 1);
    }
    if (dot < 0) {
        full = 1;
    }

    if (lz->lz_attr != NULL) {
        if (PyUnicode_Check(lz->lz_attr)) {
            fromlist = PyTuple_New(1);
            if (fromlist == NULL) {
                goto error;
            }
            Py_INCREF(lz->lz_attr);
            PyTuple_SET_ITEM(fromlist, 0, lz->lz_attr);
        }
        else {
            Py_INCREF(lz->lz_attr);
            fromlist = lz->lz_attr;
        }
    }

    PyObject *globals = PyEval_GetGlobals();

    if (PyMapping_GetOptionalItem(lz->lz_builtins, &_Py_ID(__import__),
                                  &import_func) < 0) {
        goto error;
    }
    if (import_func == NULL) {
        PyErr_SetString(PyExc_ImportError, "__import__ not found");
        goto error;
    }
    if (full) {
        obj = _PyEval_ImportNameWithImport(
            tstate, import_func, globals, globals,
            lz->lz_from, fromlist, _PyLong_GetZero()
        );
    }
    else {
        PyObject *name = PyUnicode_Substring(lz->lz_from, 0, dot);
        if (name == NULL) {
            goto error;
        }
        obj = _PyEval_ImportNameWithImport(
            tstate, import_func, globals, globals,
            name, fromlist, _PyLong_GetZero()
        );
        Py_DECREF(name);
    }
    if (obj == NULL) {
        goto error;
    }

    if (lz->lz_attr != NULL && PyUnicode_Check(lz->lz_attr)) {
        PyObject *from = obj;
        obj = _PyEval_ImportFrom(tstate, from, lz->lz_attr);
        Py_DECREF(from);
        if (obj == NULL) {
            goto error;
        }
    }

    assert(!PyLazyImport_CheckExact(obj));

    goto ok;

error:
    Py_CLEAR(obj);

    // If an error occurred and we have frame information, add it to the
    // exception.
    if (PyErr_Occurred() && lz->lz_code != NULL && lz->lz_instr_offset >= 0) {
        // Get the current exception - this already has the full traceback
        // from the access point.
        PyObject *exc = _PyErr_GetRaisedException(tstate);

        // Get import name - this can fail and set an exception.
        PyObject *import_name = _PyLazyImport_GetName(lazy_import);
        if (!import_name) {
            // Failed to get import name, just restore original exception.
            _PyErr_SetRaisedException(tstate, exc);
            goto ok;
        }

        // Resolve line number from instruction offset on demand.
        int lineno = PyCode_Addr2Line((PyCodeObject *)lz->lz_code,
                                      lz->lz_instr_offset*2);

        // Get strings - these can return NULL on encoding errors.
        const char *filename_str = PyUnicode_AsUTF8(lz->lz_code->co_filename);
        if (!filename_str) {
            // Unicode conversion failed - clear error and restore original
            // exception.
            PyErr_Clear();
            Py_DECREF(import_name);
            _PyErr_SetRaisedException(tstate, exc);
            goto ok;
        }

        const char *funcname_str = PyUnicode_AsUTF8(lz->lz_code->co_name);
        if (!funcname_str) {
            // Unicode conversion failed - clear error and restore original
            // exception.
            PyErr_Clear();
            Py_DECREF(import_name);
            _PyErr_SetRaisedException(tstate, exc);
            goto ok;
        }

        // Create a cause exception showing where the lazy import was declared.
        PyObject *msg = PyUnicode_FromFormat(
            "lazy import of '%U' raised an exception during resolution",
            import_name
        );
        Py_DECREF(import_name); // Done with import_name.

        if (!msg) {
            // Failed to create message - restore original exception.
            _PyErr_SetRaisedException(tstate, exc);
            goto ok;
        }

        PyObject *cause_exc = PyObject_CallOneArg(PyExc_ImportError, msg);
        Py_DECREF(msg);  // Done with msg.

        if (!cause_exc) {
            // Failed to create exception - restore original.
            _PyErr_SetRaisedException(tstate, exc);
            goto ok;
        }

        // Add traceback entry for the lazy import declaration.
        _PyErr_SetRaisedException(tstate, cause_exc);
        _PyTraceback_Add(funcname_str, filename_str, lineno);
        PyObject *cause_with_tb = _PyErr_GetRaisedException(tstate);

        // Set the cause on the original exception.
        PyException_SetCause(exc, cause_with_tb);  // Steals ref to cause_with_tb.

        // Restore the original exception with its full traceback.
        _PyErr_SetRaisedException(tstate, exc);
    }

ok:
    if (PySet_Discard(importing, lazy_import) < 0) {
        Py_CLEAR(obj);
    }

    // Release the global import lock.
    _PyImport_ReleaseLock(interp);

    Py_XDECREF(fromlist);
    Py_XDECREF(import_func);
    return obj;
}

static PyObject *
import_find_and_load(PyThreadState *tstate, PyObject *abs_name)
{
    PyObject *mod = NULL;
    PyInterpreterState *interp = tstate->interp;
    int import_time = _PyInterpreterState_GetConfig(interp)->import_time;
#define import_level FIND_AND_LOAD(interp).import_level
#define accumulated FIND_AND_LOAD(interp).accumulated

    PyTime_t t1 = 0, accumulated_copy = accumulated;

    /* XOptions is initialized after first some imports.
     * So we can't have negative cache before completed initialization.
     * Anyway, importlib._find_and_load is much slower than
     * _PyDict_GetItemIdWithError().
     */
    if (import_time) {
        _IMPORT_TIME_HEADER(interp);

        import_level++;
        // ignore error: don't block import if reading the clock fails
        (void)PyTime_PerfCounterRaw(&t1);
        accumulated = 0;
    }

    if (PyDTrace_IMPORT_FIND_LOAD_START_ENABLED())
        PyDTrace_IMPORT_FIND_LOAD_START(PyUnicode_AsUTF8(abs_name));

    mod = PyObject_CallMethodObjArgs(IMPORTLIB(interp), &_Py_ID(_find_and_load),
                                     abs_name, IMPORT_FUNC(interp), NULL);

    if (PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED())
        PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name),
                                       mod != NULL);

    if (import_time) {
        PyTime_t t2;
        (void)PyTime_PerfCounterRaw(&t2);
        PyTime_t cum = t2 - t1;

        import_level--;
        fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n",
                (long)_PyTime_AsMicroseconds(cum - accumulated, _PyTime_ROUND_CEILING),
                (long)_PyTime_AsMicroseconds(cum, _PyTime_ROUND_CEILING),
                import_level*2, "", PyUnicode_AsUTF8(abs_name));

        accumulated = accumulated_copy + cum;
    }

    return mod;
#undef import_level
#undef accumulated
}

static PyObject *
get_abs_name(PyThreadState *tstate, PyObject *name, PyObject *globals,
             int level)
{
    if (level > 0) {
        return resolve_name(tstate, name, globals, level);
    }
    if (PyUnicode_GET_LENGTH(name) == 0) {
        _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name");
        return NULL;
    }
    return Py_NewRef(name);
}

PyObject *
_PyImport_GetAbsName(PyThreadState *tstate, PyObject *name,
                     PyObject *globals, int level)
{
    return get_abs_name(tstate, name, globals, level);
}


PyObject *
PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
                                 PyObject *locals, PyObject *fromlist,
                                 int level)
{
    PyThreadState *tstate = _PyThreadState_GET();
    PyObject *abs_name = NULL;
    PyObject *final_mod = NULL;
    PyObject *mod = NULL;
    PyInterpreterState *interp = tstate->interp;
    int has_from;

    if (name == NULL) {
        _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name");
        goto error;
    }

    /* The below code is importlib.__import__() & _gcd_import(), ported to C
       for added performance. */

    if (!PyUnicode_Check(name)) {
        _PyErr_SetString(tstate, PyExc_TypeError,
                         "module name must be a string");
        goto error;
    }
    if (level < 0) {
        _PyErr_SetString(tstate, PyExc_ValueError, "level must be >= 0");
        goto error;
    }

    abs_name = get_abs_name(tstate, name, globals, level);
    if (abs_name == NULL) {
        goto error;
    }

    mod = import_get_module(tstate, abs_name);
    if (mod == NULL && _PyErr_Occurred(tstate)) {
        goto error;
    }

    if (mod != NULL && mod != Py_None) {
        if (import_ensure_initialized(tstate->interp, mod, abs_name) < 0) {
            goto error;
        }
        /* Verify the module is still in sys.modules. Another thread may have
           removed it (due to import failure) between our import_get_module()
           call and the _initializing check in import_ensure_initialized().
           If removed, we retry the import to preserve normal semantics: the
           caller gets the exception from the actual import failure rather
           than a synthetic error. */
        PyObject *mod_check = import_get_module(tstate, abs_name);
        if (mod_check != mod) {
            Py_XDECREF(mod_check);
            if (_PyErr_Occurred(tstate)) {
                goto error;
            }
            Py_DECREF(mod);
            mod = import_find_and_load(tstate, abs_name);
            if (mod == NULL) {
                goto error;
            }
        }
        else {
            Py_DECREF(mod_check);
        }
    }
    else {
        Py_XDECREF(mod);
        mod = import_find_and_load(tstate, abs_name);
        if (mod == NULL) {
            goto error;
        }
    }

    has_from = 0;
    if (fromlist != NULL && fromlist != Py_None) {
        has_from = PyObject_IsTrue(fromlist);
        if (has_from < 0)
            goto error;
    }
    if (!has_from) {
        Py_ssize_t len = PyUnicode_GET_LENGTH(name);
        if (level == 0 || len > 0) {
            Py_ssize_t dot;

            dot = PyUnicode_FindChar(name, '.', 0, len, 1);
            if (dot == -2) {
                goto error;
            }

            if (dot == -1) {
                /* No dot in module name, simple exit */
                final_mod = Py_NewRef(mod);
                goto error;
            }

            if (level == 0) {
                PyObject *front = PyUnicode_Substring(name, 0, dot);
                if (front == NULL) {
                    goto error;
                }

                final_mod = PyImport_ImportModuleLevelObject(front, NULL, NULL, NULL, 0);
                Py_DECREF(front);
            }
            else {
                Py_ssize_t cut_off = len - dot;
                Py_ssize_t abs_name_len = PyUnicode_GET_LENGTH(abs_name);
                PyObject *to_return = PyUnicode_Substring(abs_name, 0,
                                                        abs_name_len - cut_off);
                if (to_return == NULL) {
                    goto error;
                }

                final_mod = import_get_module(tstate, to_return);
                if (final_mod == NULL) {
                    if (!_PyErr_Occurred(tstate)) {
                        _PyErr_Format(tstate, PyExc_KeyError,
                                      "%R not in sys.modules as expected",
                                      to_return);
                    }
                    Py_DECREF(to_return);
                    goto error;
                }

                Py_DECREF(to_return);
            }
        }
        else {
            final_mod = Py_NewRef(mod);
        }
    }
    else {
        int has_path = PyObject_HasAttrWithError(mod, &_Py_ID(__path__));
        if (has_path < 0) {
            goto error;
        }
        if (has_path) {
            final_mod = PyObject_CallMethodObjArgs(
                        IMPORTLIB(interp), &_Py_ID(_handle_fromlist),
                        mod, fromlist, IMPORT_FUNC(interp), NULL);
        }
        else {
            final_mod = Py_NewRef(mod);
        }
    }

  error:
    Py_XDECREF(abs_name);
    Py_XDECREF(mod);
    if (final_mod == NULL) {
        remove_importlib_frames(tstate);
    }
    return final_mod;
}

// ensure we have the set for the parent module name in sys.lazy_modules.
// Returns a new reference.
static PyObject *
ensure_lazy_pending_submodules(PyDictObject *lazy_modules, PyObject *parent)
{
    PyObject *lazy_submodules;
    Py_BEGIN_CRITICAL_SECTION(lazy_modules);
    int err = _PyDict_GetItemRef_Unicode_LockHeld(lazy_modules, parent,
                                                  &lazy_submodules);
    if (err == 0) {
        // value isn't present
        lazy_submodules = PySet_New(NULL);
        if (lazy_submodules != NULL &&
            _PyDict_SetItem_LockHeld(lazy_modules, parent,
                                     lazy_submodules) < 0) {
            Py_CLEAR(lazy_submodules);
        }
    }
    Py_END_CRITICAL_SECTION();
    return lazy_submodules;
}

// Records all parent-child relationships in lazy_pending_submodules
// for a lazily imported module name. When a parent module's attribute
// is accessed, _Py_module_getattro_impl will check lazy_pending_submodules
// and trigger the import.
static int
register_lazy_on_parent(PyThreadState *tstate, PyObject *name)
{
    int ret = -1;
    PyObject *parent = NULL;
    PyObject *child = NULL;

    PyInterpreterState *interp = tstate->interp;
    PyObject *lazy_pending_submodules = LAZY_PENDING_SUBMODULES(interp);
    assert(lazy_pending_submodules != NULL);

    Py_INCREF(name);
    while (true) {
        Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0,
                                            PyUnicode_GET_LENGTH(name), -1);
        if (dot < 0) {
            PyObject *lazy_submodules = ensure_lazy_pending_submodules(
                (PyDictObject *)lazy_pending_submodules, name);
            if (lazy_submodules == NULL) {
                goto done;
            }
            Py_DECREF(lazy_submodules);
            ret = 0;
            goto done;
        }
        parent = PyUnicode_Substring(name, 0, dot);
        if (parent == NULL) {
            goto done;
        }
        Py_XDECREF(child);
        child = PyUnicode_Substring(name, dot + 1, PyUnicode_GET_LENGTH(name));
        if (child == NULL) {
            goto done;
        }

        PyObject *lazy_submodules = ensure_lazy_pending_submodules(
            (PyDictObject *)lazy_pending_submodules, parent);
        if (lazy_submodules == NULL) {
            goto done;
        }

        if (PySet_Add(lazy_submodules, child) < 0) {
            Py_DECREF(lazy_submodules);
            goto done;
        }
        Py_DECREF(lazy_submodules);

        Py_SETREF(name, parent);
        parent = NULL;
    }

done:
    Py_XDECREF(child);
    Py_XDECREF(parent);
    Py_XDECREF(name);
    return ret;
}

static int
register_from_lazy_on_parent(PyThreadState *tstate, PyObject *abs_name,
                             PyObject *from)
{
    PyObject *fromname = PyUnicode_FromFormat("%U.%U", abs_name, from);
    if (fromname == NULL) {
        return -1;
    }

    // Add the module name to sys.lazy_modules set (PEP 810).
    PyObject *lazy_modules = LAZY_MODULES(tstate->interp);
    if (PySet_Add(lazy_modules, fromname) < 0) {
        Py_DECREF(fromname);
        return -1;
    }

    int res = register_lazy_on_parent(tstate, fromname);
    Py_DECREF(fromname);
    return res;
}

PyObject *
_PyImport_TryLoadLazySubmodule(PyObject *mod_name, PyObject *attr_name)
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    PyObject *lazy_pending = LAZY_PENDING_SUBMODULES(interp);
    if (lazy_pending == NULL) {
        return NULL;
    }

    PyObject *pending_set;
    int rc = PyDict_GetItemRef(lazy_pending, mod_name, &pending_set);
    if (rc <= 0) {
        return NULL;
    }

    int contains = PySet_Contains(pending_set, attr_name);
    if (contains <= 0) {
        Py_DECREF(pending_set);
        return NULL;
    }

    PyObject *full_name = PyUnicode_FromFormat("%U.%U", mod_name, attr_name);
    if (full_name == NULL) {
        Py_DECREF(pending_set);
        return NULL;
    }

    PyObject *mod = PyImport_ImportModuleLevelObject(
        full_name, NULL, NULL, NULL, 0);
    if (mod == NULL) {
        Py_DECREF(pending_set);
        Py_DECREF(full_name);
        return NULL;
    }
    Py_DECREF(mod);

    if (PySet_Discard(pending_set, attr_name) < 0) {
        Py_DECREF(pending_set);
        Py_DECREF(full_name);
        return NULL;
    }
    Py_DECREF(pending_set);

    PyObject *submod = PyImport_GetModule(full_name);
    Py_DECREF(full_name);
    return submod;
}

PyObject *
_PyImport_LazyImportModuleLevelObject(PyThreadState *tstate,
                                      PyObject *name, PyObject *builtins,
                                      PyObject *globals, PyObject *locals,
                                      PyObject *fromlist, int level)
{
    assert(name != NULL);
    if (!PyUnicode_Check(name)) {
        _PyErr_Format(tstate, PyExc_TypeError,
                      "module name must be a string, got %T", name);
        return NULL;
    }
    if (level < 0) {
        _PyErr_SetString(tstate, PyExc_ValueError, "level must be >= 0");
        return NULL;
    }

    PyObject *abs_name = get_abs_name(tstate, name, globals, level);
    if (abs_name == NULL) {
        return NULL;
    }

    PyInterpreterState *interp = tstate->interp;
    _PyInterpreterFrame *frame = _PyEval_GetFrame();
    if (frame == NULL || frame->f_globals != frame->f_locals) {
        Py_DECREF(abs_name);
        PyErr_SetString(PyExc_SyntaxError,
                        "'lazy import' is only allowed at module level");
        return NULL;
    }

    // Check if the filter disables the lazy import.
    // We must hold a reference to the filter while calling it to prevent
    // use-after-free if another thread replaces it via
    // PyImport_SetLazyImportsFilter.
    LAZY_IMPORTS_LOCK(interp);
    PyObject *filter = Py_XNewRef(LAZY_IMPORTS_FILTER(interp));
    LAZY_IMPORTS_UNLOCK(interp);

    if (filter != NULL) {
        PyObject *modname;
        if (PyDict_GetItemRef(globals, &_Py_ID(__name__), &modname) < 0) {
            Py_DECREF(filter);
            Py_DECREF(abs_name);
            return NULL;
        }
        if (modname == NULL) {
            assert(!PyErr_Occurred());
            modname = Py_NewRef(Py_None);
        }
        if (fromlist == NULL) {
            assert(!PyErr_Occurred());
            fromlist = Py_NewRef(Py_None);
        }
        PyObject *args[] = {modname, abs_name, fromlist};
        PyObject *res = PyObject_Vectorcall(filter, args, 3, NULL);

        Py_DECREF(modname);
        Py_DECREF(filter);

        if (res == NULL) {
            Py_DECREF(abs_name);
            return NULL;
        }

        int is_true = PyObject_IsTrue(res);
        Py_DECREF(res);

        if (is_true < 0) {
            Py_DECREF(abs_name);
            return NULL;
        }
        if (!is_true) {
            Py_DECREF(abs_name);
            return PyImport_ImportModuleLevelObject(
                name, globals, locals, fromlist, level
            );
        }
    }

    // here, 'filter' is either NULL or is equivalent to a borrowed reference
    PyObject *res = _PyLazyImport_New(frame, builtins, abs_name, fromlist);
    if (res == NULL) {
        Py_DECREF(abs_name);
        return NULL;
    }

    // Add the module name to sys.lazy_modules set (PEP 810).
    PyObject *lazy_modules = LAZY_MODULES(tstate->interp);
    if (PySet_Add(lazy_modules, abs_name) < 0) {
        goto error;
    }

    if (fromlist && PyUnicode_Check(fromlist)) {
        if (register_from_lazy_on_parent(tstate, abs_name, fromlist) < 0) {
            goto error;
        }
    }
    else if (fromlist && PyTuple_Check(fromlist) &&
             PyTuple_GET_SIZE(fromlist)) {
        for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(fromlist); i++) {
            if (register_from_lazy_on_parent(tstate, abs_name,
                                             PyTuple_GET_ITEM(fromlist, i)) < 0)
            {
                goto error;
            }
        }
    }
    else if (register_lazy_on_parent(tstate, abs_name) < 0) {
        goto error;
    }

    Py_DECREF(abs_name);
    return res;
error:
    Py_DECREF(abs_name);
    Py_DECREF(res);
    return NULL;
}

PyObject *
PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals,
                           PyObject *fromlist, int level)
{
    PyObject *nameobj, *mod;
    nameobj = PyUnicode_FromString(name);
    if (nameobj == NULL)
        return NULL;
    mod = PyImport_ImportModuleLevelObject(nameobj, globals, locals,
                                           fromlist, level);
    Py_DECREF(nameobj);
    return mod;
}


/* Re-import a module of any kind and return its module object, WITH
   INCREMENTED REFERENCE COUNT */

PyObject *
PyImport_ReloadModule(PyObject *m)
{
    PyObject *reloaded_module = NULL;
    PyObject *importlib = PyImport_GetModule(&_Py_ID(importlib));
    if (importlib == NULL) {
        if (PyErr_Occurred()) {
            return NULL;
        }

        importlib = PyImport_ImportModule("importlib");
        if (importlib == NULL) {
            return NULL;
        }
    }

    reloaded_module = PyObject_CallMethodOneArg(importlib, &_Py_ID(reload), m);
    Py_DECREF(importlib);
    return reloaded_module;
}


/* Higher-level import emulator which emulates the "import" statement
   more accurately -- it invokes the __import__() function from the
   builtins of the current globals.  This means that the import is
   done using whatever import hooks are installed in the current
   environment.
   A dummy list ["__doc__"] is passed as the 4th argument so that
   e.g. PyImport_Import(PyUnicode_FromString("win32com.client.gencache"))
   will return <module "gencache"> instead of <module "win32com">. */

PyObject *
PyImport_Import(PyObject *module_name)
{
    PyThreadState *tstate = _PyThreadState_GET();
    PyObject *globals = NULL;
    PyObject *import = NULL;
    PyObject *builtins = NULL;
    PyObject *r = NULL;

    PyObject *from_list = PyList_New(0);
    if (from_list == NULL) {
        goto err;
    }

    /* Get the builtins from current globals */
    globals = PyEval_GetGlobals();  // borrowed
    if (globals != NULL) {
        Py_INCREF(globals);
        // XXX Use _PyEval_EnsureBuiltins()?
        builtins = PyObject_GetItem(globals, &_Py_ID(__builtins__));
        if (builtins == NULL) {
            // XXX Fall back to interp->builtins or sys.modules['builtins']?
            goto err;
        }
    }
    else if (_PyErr_Occurred(tstate)) {
        goto err;
    }
    else {
        /* No globals -- use standard builtins, and fake globals */
        globals = PyDict_New();
        if (globals == NULL) {
            goto err;
        }
        if (_PyEval_EnsureBuiltinsWithModule(tstate, globals, &builtins) < 0) {
            goto err;
        }
    }

    /* Get the __import__ function from the builtins */
    if (PyDict_Check(builtins)) {
        import = PyObject_GetItem(builtins, &_Py_ID(__import__));
        if (import == NULL) {
            _PyErr_SetObject(tstate, PyExc_KeyError, &_Py_ID(__import__));
        }
    }
    else
        import = PyObject_GetAttr(builtins, &_Py_ID(__import__));
    if (import == NULL)
        goto err;

    /* Call the __import__ function with the proper argument list
       Always use absolute import here.
       Calling for side-effect of import. */
    r = PyObject_CallFunction(import, "OOOOi", module_name, globals,
                              globals, from_list, 0, NULL);
    if (r == NULL)
        goto err;
    Py_DECREF(r);

    r = import_get_module(tstate, module_name);
    if (r == NULL && !_PyErr_Occurred(tstate)) {
        _PyErr_SetObject(tstate, PyExc_KeyError, module_name);
    }

  err:
    Py_XDECREF(globals);
    Py_XDECREF(builtins);
    Py_XDECREF(import);
    Py_XDECREF(from_list);

    return r;
}


/*********************/
/* runtime lifecycle */
/*********************/

PyStatus
_PyImport_Init(void)
{
    if (INITTAB != NULL) {
        return _PyStatus_ERR("global import state already initialized");
    }
    if (init_builtin_modules_table() != 0) {
        return PyStatus_NoMemory();
    }
    return _PyStatus_OK();
}

void
_PyImport_Fini(void)
{
    /* Destroy the database used by _PyImport_{Fixup,Find}Extension */
    // XXX Should we actually leave them (mostly) intact, since we don't
    // ever dlclose() the module files?
    _extensions_cache_clear_all();

    /* Free memory allocated by _PyImport_Init() */
    fini_builtin_modules_table();
}

void
_PyImport_Fini2(void)
{
    // Reset PyImport_Inittab
    PyImport_Inittab = _PyImport_Inittab;

    /* Free memory allocated by PyImport_ExtendInittab() */
    _PyMem_DefaultRawFree(inittab_copy);
    inittab_copy = NULL;
}


/*************************/
/* interpreter lifecycle */
/*************************/

PyStatus
_PyImport_InitCore(PyThreadState *tstate, PyObject *sysmod, int importlib)
{
    // XXX Initialize here: interp->modules and interp->import_func.
    // XXX Initialize here: sys.modules and sys.meta_path.

    if (importlib) {
        /* This call sets up builtin and frozen import support */
        if (init_importlib(tstate, sysmod) < 0) {
            return _PyStatus_ERR("failed to initialize importlib");
        }
    }

    return _PyStatus_OK();
}

/* In some corner cases it is important to be sure that the import
   machinery has been initialized (or not cleaned up yet).  For
   example, see issue #4236 and PyModule_Create2(). */

int
_PyImport_IsInitialized(PyInterpreterState *interp)
{
    if (MODULES(interp) == NULL)
        return 0;
    return 1;
}

/* Clear the direct per-interpreter import state, if not cleared already. */
void
_PyImport_ClearCore(PyInterpreterState *interp)
{
    /* interp->modules should have been cleaned up and cleared already
       by _PyImport_FiniCore(). */
    Py_CLEAR(MODULES(interp));
    Py_CLEAR(MODULES_BY_INDEX(interp));
    Py_CLEAR(IMPORTLIB(interp));
    Py_CLEAR(IMPORT_FUNC(interp));
    Py_CLEAR(LAZY_IMPORT_FUNC(interp));
    Py_CLEAR(interp->imports.lazy_pending_submodules);
    Py_CLEAR(interp->imports.lazy_modules);
    Py_CLEAR(interp->imports.lazy_importing_modules);
    Py_CLEAR(interp->imports.lazy_imports_filter);
}

void
_PyImport_FiniCore(PyInterpreterState *interp)
{
    int verbose = _PyInterpreterState_GetConfig(interp)->verbose;

    if (_PySys_ClearAttrString(interp, "meta_path", verbose) < 0) {
        PyErr_FormatUnraisable("Exception ignored while "
                               "clearing sys.meta_path");
    }

    // XXX Pull in most of finalize_modules() in pylifecycle.c.

    if (_PySys_ClearAttrString(interp, "modules", verbose) < 0) {
        PyErr_FormatUnraisable("Exception ignored while "
                               "clearing sys.modules");
    }

    _PyImport_ClearCore(interp);
}

// XXX Add something like _PyImport_Disable() for use early in interp fini?


/* "external" imports */

static int
init_zipimport(PyThreadState *tstate, int verbose)
{
    PyObject *path_hooks = PySys_GetAttrString("path_hooks");
    if (path_hooks == NULL) {
        return -1;
    }

    if (verbose) {
        PySys_WriteStderr("# installing zipimport hook\n");
    }

    PyObject *zipimporter = PyImport_ImportModuleAttrString("zipimport", "zipimporter");
    if (zipimporter == NULL) {
        _PyErr_Clear(tstate); /* No zipimporter object -- okay */
        if (verbose) {
            PySys_WriteStderr("# can't import zipimport.zipimporter\n");
        }
    }
    else {
        /* sys.path_hooks.insert(0, zipimporter) */
        int err = PyList_Insert(path_hooks, 0, zipimporter);
        Py_DECREF(zipimporter);
        if (err < 0) {
            Py_DECREF(path_hooks);
            return -1;
        }
        if (verbose) {
            PySys_WriteStderr("# installed zipimport hook\n");
        }
    }
    Py_DECREF(path_hooks);

    return 0;
}

PyStatus
_PyImport_InitExternal(PyThreadState *tstate)
{
    int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose;

    // XXX Initialize here: sys.path_hooks and sys.path_importer_cache.

    if (init_importlib_external(tstate->interp) != 0) {
        _PyErr_Print(tstate);
        return _PyStatus_ERR("external importer setup failed");
    }

    if (init_zipimport(tstate, verbose) != 0) {
        PyErr_Print();
        return _PyStatus_ERR("initializing zipimport failed");
    }

    return _PyStatus_OK();
}

void
_PyImport_FiniExternal(PyInterpreterState *interp)
{
    int verbose = _PyInterpreterState_GetConfig(interp)->verbose;

    // XXX Uninstall importlib metapath importers here?

    if (_PySys_ClearAttrString(interp, "path_importer_cache", verbose) < 0) {
        PyErr_FormatUnraisable("Exception ignored while "
                               "clearing sys.path_importer_cache");
    }
    if (_PySys_ClearAttrString(interp, "path_hooks", verbose) < 0) {
        PyErr_FormatUnraisable("Exception ignored while "
                               "clearing sys.path_hooks");
    }
}


/******************/
/* module helpers */
/******************/

PyObject *
PyImport_ImportModuleAttr(PyObject *modname, PyObject *attrname)
{
    PyObject *mod = PyImport_Import(modname);
    if (mod == NULL) {
        return NULL;
    }
    PyObject *result = PyObject_GetAttr(mod, attrname);
    Py_DECREF(mod);
    return result;
}

PyObject *
PyImport_ImportModuleAttrString(const char *modname, const char *attrname)
{
    PyObject *pmodname = PyUnicode_FromString(modname);
    if (pmodname == NULL) {
        return NULL;
    }
    PyObject *pattrname = PyUnicode_FromString(attrname);
    if (pattrname == NULL) {
        Py_DECREF(pmodname);
        return NULL;
    }
    PyObject *result = PyImport_ImportModuleAttr(pmodname, pattrname);
    Py_DECREF(pattrname);
    Py_DECREF(pmodname);
    return result;
}

int
PyImport_SetLazyImportsFilter(PyObject *filter)
{
    if (filter == Py_None) {
        filter = NULL;
    }
    if (filter != NULL && !PyCallable_Check(filter)) {
        PyErr_SetString(PyExc_ValueError,
                        "filter provided but is not callable");
        return -1;
    }

    PyInterpreterState *interp = _PyInterpreterState_GET();
    // Exchange the filter w/ the lock held. We can't use Py_XSETREF
    // because we need to release the lock before the decref.
    LAZY_IMPORTS_LOCK(interp);
    PyObject *old = LAZY_IMPORTS_FILTER(interp);
    LAZY_IMPORTS_FILTER(interp) = Py_XNewRef(filter);
    LAZY_IMPORTS_UNLOCK(interp);
    Py_XDECREF(old);
    return 0;
}

/* Return a strong reference to the current lazy imports filter
 * or NULL if none exists. This function always succeeds.
 */
PyObject *
PyImport_GetLazyImportsFilter(void)
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    LAZY_IMPORTS_LOCK(interp);
    PyObject *res = Py_XNewRef(LAZY_IMPORTS_FILTER(interp));
    LAZY_IMPORTS_UNLOCK(interp);
    return res;
}

int
PyImport_SetLazyImportsMode(PyImport_LazyImportsMode mode)
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    FT_ATOMIC_STORE_INT_RELAXED(LAZY_IMPORTS_MODE(interp), mode);
    return 0;
}

/* Checks if lazy imports is globally enabled or disabled. Return 1 when
 * globally forced on, 0 when globally forced off, or -1 when not set.*/
PyImport_LazyImportsMode
PyImport_GetLazyImportsMode(void)
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    return FT_ATOMIC_LOAD_INT_RELAXED(LAZY_IMPORTS_MODE(interp));
}

/**************/
/* the module */
/**************/

/*[clinic input]
_imp.lock_held

Return True if the import lock is currently held, else False.

On platforms without threads, return False.
[clinic start generated code]*/

static PyObject *
_imp_lock_held_impl(PyObject *module)
/*[clinic end generated code: output=8b89384b5e1963fc input=9b088f9b217d9bdf]*/
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    return PyBool_FromLong(PyMutex_IsLocked(&IMPORT_LOCK(interp).mutex));
}

/*[clinic input]
_imp.acquire_lock

Acquires the interpreter's import lock for the current thread.

This lock should be used by import hooks to ensure thread-safety when
importing modules.  On platforms without threads, this function does
nothing.
[clinic start generated code]*/

static PyObject *
_imp_acquire_lock_impl(PyObject *module)
/*[clinic end generated code: output=1aff58cb0ee1b026 input=60e9c1b4ab471ead]*/
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    _PyImport_AcquireLock(interp);
    Py_RETURN_NONE;
}

/*[clinic input]
_imp.release_lock

Release the interpreter's import lock.

On platforms without threads, this function does nothing.
[clinic start generated code]*/

static PyObject *
_imp_release_lock_impl(PyObject *module)
/*[clinic end generated code: output=7faab6d0be178b0a input=934fb11516dd778b]*/
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    if (!_PyRecursiveMutex_IsLockedByCurrentThread(&IMPORT_LOCK(interp))) {
        PyErr_SetString(PyExc_RuntimeError,
                        "not holding the import lock");
        return NULL;
    }
    _PyImport_ReleaseLock(interp);
    Py_RETURN_NONE;
}


/*[clinic input]
_imp._fix_co_filename

    code: object(type="PyCodeObject *", subclass_of="&PyCode_Type")
        Code object to change.

    path: unicode
        File path to use.
    /

Changes code.co_filename to specify the passed-in file path.
[clinic start generated code]*/

static PyObject *
_imp__fix_co_filename_impl(PyObject *module, PyCodeObject *code,
                           PyObject *path)
/*[clinic end generated code: output=1d002f100235587d input=895ba50e78b82f05]*/

{
    update_compiled_module(code, path);

    Py_RETURN_NONE;
}


/*[clinic input]
_imp.create_builtin

    spec: object
    /

Create an extension module.
[clinic start generated code]*/

static PyObject *
_imp_create_builtin(PyObject *module, PyObject *spec)
/*[clinic end generated code: output=ace7ff22271e6f39 input=37f966f890384e47]*/
{
    PyThreadState *tstate = _PyThreadState_GET();

    PyObject *name = PyObject_GetAttrString(spec, "name");
    if (name == NULL) {
        return NULL;
    }

    if (!PyUnicode_Check(name)) {
        PyErr_Format(PyExc_TypeError,
                     "name must be string, not %.200s",
                     Py_TYPE(name)->tp_name);
        Py_DECREF(name);
        return NULL;
    }

    if (PyUnicode_GetLength(name) == 0) {
        PyErr_Format(PyExc_ValueError, "name must not be empty");
        Py_DECREF(name);
        return NULL;
    }

    PyObject *mod = create_builtin(tstate, name, spec, NULL);
    Py_DECREF(name);
    return mod;
}


/*[clinic input]
_imp.extension_suffixes

Returns the list of file suffixes used to identify extension modules.
[clinic start generated code]*/

static PyObject *
_imp_extension_suffixes_impl(PyObject *module)
/*[clinic end generated code: output=0bf346e25a8f0cd3 input=ecdeeecfcb6f839e]*/
{
    PyObject *list;

    list = PyList_New(0);
    if (list == NULL)
        return NULL;
#ifdef HAVE_DYNAMIC_LOADING
    const char *suffix;
    unsigned int index = 0;

    while ((suffix = _PyImport_DynLoadFiletab[index])) {
        PyObject *item = PyUnicode_FromString(suffix);
        if (item == NULL) {
            Py_DECREF(list);
            return NULL;
        }
        if (PyList_Append(list, item) < 0) {
            Py_DECREF(list);
            Py_DECREF(item);
            return NULL;
        }
        Py_DECREF(item);
        index += 1;
    }
#endif
    return list;
}

/*[clinic input]
_imp.init_frozen

    name: unicode
    /

Initializes a frozen module.
[clinic start generated code]*/

static PyObject *
_imp_init_frozen_impl(PyObject *module, PyObject *name)
/*[clinic end generated code: output=fc0511ed869fd69c input=13019adfc04f3fb3]*/
{
    PyThreadState *tstate = _PyThreadState_GET();
    int ret;

    ret = PyImport_ImportFrozenModuleObject(name);
    if (ret < 0)
        return NULL;
    if (ret == 0) {
        Py_RETURN_NONE;
    }
    return import_add_module(tstate, name);
}

/*[clinic input]
@permit_long_summary
_imp.find_frozen

    name: unicode
    /
    *
    withdata: bool = False

Return info about the corresponding frozen module (if there is one) or None.

The returned info (a 2-tuple):

 * data         the raw marshalled bytes
 * is_package   whether or not it is a package
 * origname     the originally frozen module's name, or None if not
                a stdlib module (this will usually be the same as
                the module's current name)
[clinic start generated code]*/

static PyObject *
_imp_find_frozen_impl(PyObject *module, PyObject *name, int withdata)
/*[clinic end generated code: output=8c1c3c7f925397a5 input=30a7a50da49eca97]*/
{
    struct frozen_info info;
    frozen_status status = find_frozen(name, &info);
    if (status == FROZEN_NOT_FOUND || status == FROZEN_DISABLED) {
        Py_RETURN_NONE;
    }
    else if (status == FROZEN_BAD_NAME) {
        Py_RETURN_NONE;
    }
    else if (status != FROZEN_OKAY) {
        set_frozen_error(status, name);
        return NULL;
    }

    PyObject *data = NULL;
    if (withdata) {
        data = PyMemoryView_FromMemory((char *)info.data, info.size, PyBUF_READ);
        if (data == NULL) {
            return NULL;
        }
    }

    PyObject *origname = NULL;
    if (info.origname != NULL && info.origname[0] != '\0') {
        origname = PyUnicode_FromString(info.origname);
        if (origname == NULL) {
            Py_XDECREF(data);
            return NULL;
        }
    }

    PyObject *result = PyTuple_Pack(3, data ? data : Py_None,
                                    info.is_package ? Py_True : Py_False,
                                    origname ? origname : Py_None);
    Py_XDECREF(origname);
    Py_XDECREF(data);
    return result;
}

/*[clinic input]
_imp.get_frozen_object

    name: unicode
    data as dataobj: object = None
    /

Create a code object for a frozen module.
[clinic start generated code]*/

static PyObject *
_imp_get_frozen_object_impl(PyObject *module, PyObject *name,
                            PyObject *dataobj)
/*[clinic end generated code: output=54368a673a35e745 input=034bdb88f6460b7b]*/
{
    struct frozen_info info = {0};
    Py_buffer buf = {0};
    if (PyObject_CheckBuffer(dataobj)) {
        if (PyObject_GetBuffer(dataobj, &buf, PyBUF_SIMPLE) != 0) {
            return NULL;
        }
        info.data = (const char *)buf.buf;
        info.size = buf.len;
    }
    else if (dataobj != Py_None) {
        _PyArg_BadArgument("get_frozen_object", "argument 2", "bytes", dataobj);
        return NULL;
    }
    else {
        frozen_status status = find_frozen(name, &info);
        if (status != FROZEN_OKAY) {
            set_frozen_error(status, name);
            return NULL;
        }
    }

    if (info.nameobj == NULL) {
        info.nameobj = name;
    }
    if (info.size == 0) {
        /* Does not contain executable code. */
        set_frozen_error(FROZEN_INVALID, name);
        return NULL;
    }

    PyInterpreterState *interp = _PyInterpreterState_GET();
    PyObject *codeobj = unmarshal_frozen_code(interp, &info);
    if (dataobj != Py_None) {
        PyBuffer_Release(&buf);
    }
    return codeobj;
}

/*[clinic input]
_imp.is_frozen_package

    name: unicode
    /

Returns True if the module name is of a frozen package.
[clinic start generated code]*/

static PyObject *
_imp_is_frozen_package_impl(PyObject *module, PyObject *name)
/*[clinic end generated code: output=e70cbdb45784a1c9 input=81b6cdecd080fbb8]*/
{
    struct frozen_info info;
    frozen_status status = find_frozen(name, &info);
    if (status != FROZEN_OKAY && status != FROZEN_EXCLUDED) {
        set_frozen_error(status, name);
        return NULL;
    }
    return PyBool_FromLong(info.is_package);
}

/*[clinic input]
_imp.is_builtin

    name: unicode
    /

Returns True if the module name corresponds to a built-in module.
[clinic start generated code]*/

static PyObject *
_imp_is_builtin_impl(PyObject *module, PyObject *name)
/*[clinic end generated code: output=3bfd1162e2d3be82 input=86befdac021dd1c7]*/
{
    return PyLong_FromLong(is_builtin(name));
}

/*[clinic input]
_imp.is_frozen

    name: unicode
    /

Returns True if the module name corresponds to a frozen module.
[clinic start generated code]*/

static PyObject *
_imp_is_frozen_impl(PyObject *module, PyObject *name)
/*[clinic end generated code: output=01f408f5ec0f2577 input=7301dbca1897d66b]*/
{
    struct frozen_info info;
    frozen_status status = find_frozen(name, &info);
    if (status != FROZEN_OKAY) {
        Py_RETURN_FALSE;
    }
    Py_RETURN_TRUE;
}

/*[clinic input]
_imp._frozen_module_names

Returns the list of available frozen modules.
[clinic start generated code]*/

static PyObject *
_imp__frozen_module_names_impl(PyObject *module)
/*[clinic end generated code: output=80609ef6256310a8 input=76237fbfa94460d2]*/
{
    return list_frozen_module_names();
}

/*[clinic input]
_imp._override_frozen_modules_for_tests

    override: int
    /

(internal-only) Override PyConfig.use_frozen_modules.

(-1: "off", 1: "on", 0: no override)
See frozen_modules() in Lib/test/support/import_helper.py.
[clinic start generated code]*/

static PyObject *
_imp__override_frozen_modules_for_tests_impl(PyObject *module, int override)
/*[clinic end generated code: output=36d5cb1594160811 input=8f1f95a3ef21aec3]*/
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    OVERRIDE_FROZEN_MODULES(interp) = override;
    Py_RETURN_NONE;
}

/*[clinic input]
@permit_long_summary
_imp._override_multi_interp_extensions_check

    override: int
    /

(internal-only) Override PyInterpreterConfig.check_multi_interp_extensions.

(-1: "never", 1: "always", 0: no override)
[clinic start generated code]*/

static PyObject *
_imp__override_multi_interp_extensions_check_impl(PyObject *module,
                                                  int override)
/*[clinic end generated code: output=3ff043af52bbf280 input=24f23f8510a7f6e7]*/
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    if (_Py_IsMainInterpreter(interp)) {
        PyErr_SetString(PyExc_RuntimeError,
                        "_imp._override_multi_interp_extensions_check() "
                        "cannot be used in the main interpreter");
        return NULL;
    }
#ifdef Py_GIL_DISABLED
    PyErr_SetString(PyExc_RuntimeError,
                    "_imp._override_multi_interp_extensions_check() "
                    "cannot be used in the free-threaded build");
    return NULL;
#else
    int oldvalue = OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK(interp);
    OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK(interp) = override;
    return PyLong_FromLong(oldvalue);
#endif
}

#ifdef HAVE_DYNAMIC_LOADING

/*[clinic input]
_imp.create_dynamic

    spec: object
    file: object = NULL
    /

Create an extension module.
[clinic start generated code]*/

static PyObject *
_imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)
/*[clinic end generated code: output=83249b827a4fde77 input=c31b954f4cf4e09d]*/
{
    FILE *fp = NULL;
    PyObject *mod = NULL;
    PyThreadState *tstate = _PyThreadState_GET();

    struct _Py_ext_module_loader_info info;
    if (_Py_ext_module_loader_info_init_from_spec(&info, spec) < 0) {
        return NULL;
    }

    struct extensions_cache_value *cached = NULL;
    mod = import_find_extension(tstate, &info, &cached);
    if (mod != NULL) {
        assert(!_PyErr_Occurred(tstate));
        assert(cached != NULL);
        /* The module might not have md_def set in certain reload cases. */
        assert(_PyModule_GetDefOrNull(mod) == NULL
                || cached->def == _PyModule_GetDefOrNull(mod));
        assert_singlephase(cached);
        goto finally;
    }
    else if (_PyErr_Occurred(tstate)) {
        goto finally;
    }
    /* Otherwise it must be multi-phase init or the first time it's loaded. */

    /* If the module was added to the global cache
     * but def->m_base.m_copy was cleared (e.g. subinterp fini)
     * then we have to do a little dance here. */
    if (cached != NULL) {
        assert(cached->def->m_base.m_copy == NULL);
        /* For now we clear the cache and move on. */
        _extensions_cache_delete(info.path, info.name);
    }

    if (PySys_Audit("import", "OOOOO", info.name, info.filename,
                    Py_None, Py_None, Py_None) < 0)
    {
        goto finally;
    }

    /* We would move this (and the fclose() below) into
     * _PyImport_GetModuleExportHooks(), but it isn't clear if the intervening
     * code relies on fp still being open. */
    if (file != NULL) {
        fp = Py_fopen(info.filename, "r");
        if (fp == NULL) {
            goto finally;
        }
    }

    PyModInitFunction p0 = NULL;
    PyModExportFunction ex0 = NULL;
    _PyImport_GetModuleExportHooks(&info, fp, &p0, &ex0);
    if (ex0) {
        mod = import_run_modexport(tstate, ex0, &info, spec);
        // Modules created from slots handle GIL enablement (Py_mod_gil slot)
        // when they're created.
        goto finally;
    }
    if (p0 == NULL) {
        goto finally;
    }

#ifdef Py_GIL_DISABLED
    // This call (and the corresponding call to _PyImport_CheckGILForModule())
    // would ideally be inside import_run_extension(). They are kept in the
    // callers for now because that would complicate the control flow inside
    // import_run_extension(). It should be possible to restructure
    // import_run_extension() to address this.
    _PyEval_EnableGILTransient(tstate);
#endif
    mod = import_run_extension(
                    tstate, p0, &info, spec, get_modules_dict(tstate, true));
#ifdef Py_GIL_DISABLED
    if (_PyImport_CheckGILForModule(mod, info.name) < 0) {
        Py_CLEAR(mod);
        goto finally;
    }
#endif

finally:
    if (fp != NULL) {
        fclose(fp);
    }
    _Py_ext_module_loader_info_clear(&info);
    return mod;
}

/*[clinic input]
_imp.exec_dynamic -> int

    mod: object
    /

Initialize an extension module.
[clinic start generated code]*/

static int
_imp_exec_dynamic_impl(PyObject *module, PyObject *mod)
/*[clinic end generated code: output=f5720ac7b465877d input=9fdbfcb250280d3a]*/
{
    return exec_builtin_or_dynamic(mod);
}


#endif /* HAVE_DYNAMIC_LOADING */

/*[clinic input]
_imp.exec_builtin -> int

    mod: object
    /

Initialize a built-in module.
[clinic start generated code]*/

static int
_imp_exec_builtin_impl(PyObject *module, PyObject *mod)
/*[clinic end generated code: output=0262447b240c038e input=7beed5a2f12a60ca]*/
{
    return exec_builtin_or_dynamic(mod);
}

/*[clinic input]
_imp.source_hash

    key: long
    source: Py_buffer
[clinic start generated code]*/

static PyObject *
_imp_source_hash_impl(PyObject *module, long key, Py_buffer *source)
/*[clinic end generated code: output=edb292448cf399ea input=9aaad1e590089789]*/
{
    union {
        uint64_t x;
        char data[sizeof(uint64_t)];
    } hash;
    hash.x = _Py_KeyedHash((uint64_t)key, source->buf, source->len);
#if !PY_LITTLE_ENDIAN
    // Force to little-endian. There really ought to be a succinct standard way
    // to do this.
    for (size_t i = 0; i < sizeof(hash.data)/2; i++) {
        char tmp = hash.data[i];
        hash.data[i] = hash.data[sizeof(hash.data) - i - 1];
        hash.data[sizeof(hash.data) - i - 1] = tmp;
    }
#endif
    return PyBytes_FromStringAndSize(hash.data, sizeof(hash.data));
}

/*[clinic input]
_imp._set_lazy_attributes
    modobj: object
    name: unicode
    /
Sets attributes to lazy submodules on the module, as side effects.
[clinic start generated code]*/

static PyObject *
_imp__set_lazy_attributes_impl(PyObject *module, PyObject *modobj,
                               PyObject *name)
/*[clinic end generated code: output=3369bb3242b1f043 input=38ea6f30956dd7d6]*/
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    if (PySet_Discard(LAZY_MODULES(interp), name) < 0) {
        return NULL;
    }
    Py_RETURN_NONE;
}

PyDoc_STRVAR(doc_imp,
"(Extremely) low-level import machinery bits as used by importlib.");

static PyMethodDef imp_methods[] = {
    _IMP_EXTENSION_SUFFIXES_METHODDEF
    _IMP_LOCK_HELD_METHODDEF
    _IMP_ACQUIRE_LOCK_METHODDEF
    _IMP_RELEASE_LOCK_METHODDEF
    _IMP_FIND_FROZEN_METHODDEF
    _IMP_GET_FROZEN_OBJECT_METHODDEF
    _IMP_IS_FROZEN_PACKAGE_METHODDEF
    _IMP_CREATE_BUILTIN_METHODDEF
    _IMP_INIT_FROZEN_METHODDEF
    _IMP_IS_BUILTIN_METHODDEF
    _IMP_IS_FROZEN_METHODDEF
    _IMP__FROZEN_MODULE_NAMES_METHODDEF
    _IMP__OVERRIDE_FROZEN_MODULES_FOR_TESTS_METHODDEF
    _IMP__OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK_METHODDEF
    _IMP_CREATE_DYNAMIC_METHODDEF
    _IMP_EXEC_DYNAMIC_METHODDEF
    _IMP_EXEC_BUILTIN_METHODDEF
    _IMP__FIX_CO_FILENAME_METHODDEF
    _IMP_SOURCE_HASH_METHODDEF
    _IMP__SET_LAZY_ATTRIBUTES_METHODDEF
    {NULL, NULL}  /* sentinel */
};


static int
imp_module_exec(PyObject *module)
{
    const wchar_t *mode = _Py_GetConfig()->check_hash_pycs_mode;
    PyObject *pyc_mode = PyUnicode_FromWideChar(mode, -1);
    if (PyModule_Add(module, "check_hash_based_pycs", pyc_mode) < 0) {
        return -1;
    }

    if (PyModule_AddIntConstant(
            module, "pyc_magic_number_token", PYC_MAGIC_NUMBER_TOKEN) < 0)
    {
        return -1;
    }

    return 0;
}


static PyModuleDef_Slot imp_slots[] = {
     _Py_ABI_SLOT,
    {Py_mod_exec, imp_module_exec},
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
    {0, NULL}
};

static struct PyModuleDef imp_module = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_imp",
    .m_doc = doc_imp,
    .m_size = 0,
    .m_methods = imp_methods,
    .m_slots = imp_slots,
};

PyMODINIT_FUNC
PyInit__imp(void)
{
    return PyModuleDef_Init(&imp_module);
}
