/* 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_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_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_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_sysmodule.h"     // _PySys_ClearAttrString()
#include "pycore_time.h"          // _PyTime_AsMicroseconds()
#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

#define PKGCONTEXT (_PyRuntime.imports.pkgcontext)


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

#define MODULES(interp) \
    (interp)->imports.modules
#define MODULES_BY_INDEX(interp) \
    (interp)->imports.modules_by_index
#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 IMPORT_LOCK(interp) \
    (interp)->imports.lock

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

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

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) {
            Py_DECREF(mod);
            remove_importlib_frames(tstate);
            return NULL;
        }
    }
    return mod;
}

/* 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;
# undef PKGCONTEXT
# 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.
     */
    PyModuleDef_Slot *slots = ex0();
    if (!slots) {
        if (!PyErr_Occurred()) {
            PyErr_Format(
                PyExc_SystemError,
                "slot export function for module %s failed without setting an exception",
                info->name);
        }
        return NULL;
    }
    if (PyErr_Occurred()) {
        PyErr_Format(
            PyExc_SystemError,
            "slot export function for module %s 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);
    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) {
                        return NULL;
                    }
                } 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());
                goto main_finally;
            }
        }
    }

main_finally:
    /* Switch back to the subinterpreter. */
    if (switched) {
        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;
    }

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

    /* Finally we handle the error return from _PyImport_RunModInitFunc(). */
    if (rc < 0) {
        _Py_ext_module_loader_result_apply_error(&res, name_buf);
        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 PyModInitFunction
lookup_inittab_initfunc(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 (PyModInitFunction)p->initfunc;
        }
    }
    // 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 = initfunc;
    if (p0 == NULL) {
        p0 = lookup_inittab_initfunc(&info);
        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_AsUTF8(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;
    return 0;
}

int
_PyImport_IsDefaultImportFunc(PyInterpreterState *interp, PyObject *func)
{
    return func == 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 (!PyDict_Check(globals)) {
        _PyErr_SetString(tstate, PyExc_TypeError, "globals must be a dict");
        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;
}

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
}

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;
    PyObject *package = 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;
    }

    if (level > 0) {
        abs_name = resolve_name(tstate, name, globals, level);
        if (abs_name == NULL)
            goto error;
    }
    else {  /* level == 0 */
        if (PyUnicode_GET_LENGTH(name) == 0) {
            _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name");
            goto error;
        }
        abs_name = Py_NewRef(name);
    }

    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;
        }
    }
    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);
    Py_XDECREF(package);
    if (final_mod == NULL) {
        remove_importlib_frames(tstate);
    }
    return final_mod;
}

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

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


/**************/
/* 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]
@permit_long_docstring_body
_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=e1a4ef049d34e7dd]*/
{
    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;
    }

    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]
_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=22a8847c201542fd]*/
{
    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]
_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=e086a2ea181f92ae]*/
{
    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]*/
{
    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. */
    FILE *fp;
    if (file != NULL) {
        fp = Py_fopen(info.filename, "r");
        if (fp == NULL) {
            goto finally;
        }
    }
    else {
        fp = NULL;
    }

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

cleanup:
    // XXX Shouldn't this happen in the error cases too (i.e. in "finally")?
    if (fp) {
        fclose(fp);
    }

finally:
    _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));
}


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