/* Module object implementation */

#include "Python.h"
#include "pycore_call.h"          // _PyObject_CallNoArgs()
#include "pycore_ceval.h"         // _PyEval_EnableGILTransient()
#include "pycore_dict.h"          // _PyDict_EnablePerThreadRefcounting()
#include "pycore_fileutils.h"     // _Py_wgetcwd
#include "pycore_import.h"        // _PyImport_GetNextModuleIndex()
#include "pycore_interp.h"        // PyInterpreterState.importlib
#include "pycore_lazyimportobject.h" // PyLazyImport_CheckExact()
#include "pycore_long.h"          // _PyLong_GetOne()
#include "pycore_modsupport.h"    // _PyModule_CreateInitialized()
#include "pycore_moduleobject.h"  // _PyModule_GetDefOrNull()
#include "pycore_object.h"        // _PyType_AllocNoTrack
#include "pycore_pyerrors.h"      // _PyErr_FormatFromCause()
#include "pycore_pystate.h"       // _PyInterpreterState_GET()
#include "pycore_slots.h"         // _PySlotIterator_Init
#include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString()
#include "pycore_weakref.h"       // FT_CLEAR_WEAKREFS()

#include "osdefs.h"               // MAXPATHLEN

#define _PyModule_CAST(op) \
    (assert(PyModule_Check(op)), _Py_CAST(PyModuleObject*, (op)))


static PyMemberDef module_members[] = {
    {"__dict__", _Py_T_OBJECT, offsetof(PyModuleObject, md_dict), Py_READONLY},
    {0}
};

static void
assert_def_missing_or_redundant(PyModuleObject *m)
{
    /* We copy all relevant info into the module object.
     * Modules created using a def keep a reference to that (statically
     * allocated) def; the info there should match what we have in the module.
     */
#ifndef NDEBUG
    if (m->md_token_is_def) {
        PyModuleDef *def = (PyModuleDef *)m->md_token;
        assert(def);
#define DO_ASSERT(F) assert (def->m_ ## F == m->md_state_ ## F);
        DO_ASSERT(size);
        DO_ASSERT(traverse);
        DO_ASSERT(clear);
        DO_ASSERT(free);
#undef DO_ASSERT
    }
#endif // NDEBUG
}


PyTypeObject PyModuleDef_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "moduledef",                                /* tp_name */
    sizeof(PyModuleDef),                        /* tp_basicsize */
    0,                                          /* tp_itemsize */
};


int
_PyModule_IsExtension(PyObject *obj)
{
    if (!PyModule_Check(obj)) {
        return 0;
    }
    PyModuleObject *module = (PyModuleObject*)obj;

    if (module->md_exec) {
        return 1;
    }
    if (module->md_token_is_def) {
        PyModuleDef *def = (PyModuleDef *)module->md_token;
        return (module->md_token_is_def && def->m_methods != NULL);
    }
    return 0;
}


PyObject*
PyModuleDef_Init(PyModuleDef* def)
{
#ifdef Py_GIL_DISABLED
    // Check that this def does not come from a non-free-threading ABI.
    //
    // This is meant as a "sanity check"; users should never rely on it.
    // In particular, if we run out of ob_flags bits, or otherwise need to
    // change some of the internals, this check can go away. Still, it
    // would be nice to keep it for the free-threading transition.
    //
    // A PyModuleDef must be initialized with PyModuleDef_HEAD_INIT,
    // which (via PyObject_HEAD_INIT) sets _Py_STATICALLY_ALLOCATED_FLAG
    // and not _Py_LEGACY_ABI_CHECK_FLAG. For PyModuleDef, these flags never
    // change.
    // This means that the lower nibble of a valid PyModuleDef's ob_flags is
    // always `_10_` (in binary; `_` is don't care).
    //
    // So, a check for these bits won't reject valid PyModuleDef.
    // Rejecting incompatible extensions is slightly less important; here's
    // how that works:
    //
    // In the pre-free-threading stable ABI, PyModuleDef_HEAD_INIT is big
    // enough to overlap with free-threading ABI's ob_flags, is all zeros
    // except for the refcount field.
    // The refcount field can be:
    // - 1 (3.11 and below)
    // - UINT_MAX >> 2 (32-bit 3.12 & 3.13)
    // - UINT_MAX (64-bit 3.12 & 3.13)
    // - 7L << 28 (3.14)
    //
    // This means that the lower nibble of *any byte* in PyModuleDef_HEAD_INIT
    // is not `_10_` -- it can be:
    // - 0b0000
    // - 0b0001
    // - 0b0011 (from UINT_MAX >> 2)
    // - 0b0111 (from 7L << 28)
    // - 0b1111 (e.g. from UINT_MAX)
    // (The values may change at runtime as the PyModuleDef is used, but
    // PyModuleDef_Init is required before using the def as a Python object,
    // so we check at least once with the initial values.
    uint16_t flags = ((PyObject*)def)->ob_flags;
    uint16_t bits = _Py_STATICALLY_ALLOCATED_FLAG | _Py_LEGACY_ABI_CHECK_FLAG;
    if ((flags & bits) != _Py_STATICALLY_ALLOCATED_FLAG) {
        const char *message = "invalid PyModuleDef, extension possibly "
            "compiled for non-free-threaded Python";
        // Write the error as unraisable: if the extension tries calling
        // any API, it's likely to segfault and lose the exception.
        PyErr_SetString(PyExc_SystemError, message);
        PyErr_WriteUnraisable(NULL);
        // But also raise the exception normally -- this is technically
        // a recoverable state.
        PyErr_SetString(PyExc_SystemError, message);
        return NULL;
    }
#endif
    assert(PyModuleDef_Type.tp_flags & Py_TPFLAGS_READY);
    if (def->m_base.m_index == 0) {
        Py_SET_REFCNT(def, 1);
        Py_SET_TYPE(def, &PyModuleDef_Type);
        def->m_base.m_index = _PyImport_GetNextModuleIndex();
    }
    return (PyObject*)def;
}

static int
module_init_dict(PyModuleObject *mod, PyObject *md_dict,
                 PyObject *name, PyObject *doc)
{
    assert(md_dict != NULL);
    if (doc == NULL)
        doc = Py_None;

    if (PyDict_SetItem(md_dict, &_Py_ID(__name__), name) != 0)
        return -1;
    if (PyDict_SetItem(md_dict, &_Py_ID(__doc__), doc) != 0)
        return -1;
    if (PyDict_SetItem(md_dict, &_Py_ID(__package__), Py_None) != 0)
        return -1;
    if (PyDict_SetItem(md_dict, &_Py_ID(__loader__), Py_None) != 0)
        return -1;
    if (PyDict_SetItem(md_dict, &_Py_ID(__spec__), Py_None) != 0)
        return -1;
    if (PyUnicode_CheckExact(name)) {
        Py_XSETREF(mod->md_name, Py_NewRef(name));
    }

    return 0;
}

static PyModuleObject *
new_module_notrack(PyTypeObject *mt)
{
    PyModuleObject *m;
    m = (PyModuleObject *)_PyType_AllocNoTrack(mt, 0);
    if (m == NULL)
        return NULL;
    m->md_state = NULL;
    m->md_weaklist = NULL;
    m->md_name = NULL;
    m->md_token_is_def = false;
#ifdef Py_GIL_DISABLED
    m->md_requires_gil = true;
#endif
    m->md_state_size = 0;
    m->md_state_traverse = NULL;
    m->md_state_clear = NULL;
    m->md_state_free = NULL;
    m->md_exec = NULL;
    m->md_token = NULL;
    m->md_dict = PyDict_New();
    if (m->md_dict == NULL) {
        Py_DECREF(m);
        return NULL;
    }
    return m;
}

/* Module dict watcher callback.
 * When a module dictionary is modified, we need to clear the keys version
 * to invalidate any cached lookups that depend on the dictionary structure.
 */
static int
module_dict_watcher(PyDict_WatchEvent event, PyObject *dict,
                    PyObject *key, PyObject *new_value)
{
    assert(PyDict_Check(dict));
    // Only if a new lazy object shows up do we need to clear the dictionary. If
    // this is adding a new key then the version will be reset anyway.
    if (event == PyDict_EVENT_MODIFIED &&
        new_value != NULL &&
        PyLazyImport_CheckExact(new_value)) {
        _PyDict_ClearKeysVersionLockHeld(dict);
    }
    return 0;
}

int
_PyModule_InitModuleDictWatcher(PyInterpreterState *interp)
{
    // This is a reserved watcher for CPython so there's no need to check for non-NULL.
    assert(interp->dict_state.watchers[MODULE_WATCHER_ID] == NULL);
    interp->dict_state.watchers[MODULE_WATCHER_ID] = &module_dict_watcher;
    return 0;
}

static void
track_module(PyModuleObject *m)
{
    _PyDict_EnablePerThreadRefcounting(m->md_dict);
    _PyObject_SetDeferredRefcount((PyObject *)m);
    PyDict_Watch(MODULE_WATCHER_ID, m->md_dict);
    PyObject_GC_Track(m);
}

static PyObject *
new_module(PyTypeObject *mt, PyObject *args, PyObject *kws)
{
    PyModuleObject *m = new_module_notrack(mt);
    if (m != NULL) {
        track_module(m);
    }
    return (PyObject *)m;
}

PyObject *
PyModule_NewObject(PyObject *name)
{
    PyModuleObject *m = new_module_notrack(&PyModule_Type);
    if (m == NULL)
        return NULL;
    if (module_init_dict(m, m->md_dict, name, NULL) != 0)
        goto fail;
    track_module(m);
    return (PyObject *)m;

 fail:
    Py_DECREF(m);
    return NULL;
}

PyObject *
PyModule_New(const char *name)
{
    PyObject *nameobj, *module;
    nameobj = PyUnicode_FromString(name);
    if (nameobj == NULL)
        return NULL;
    module = PyModule_NewObject(nameobj);
    Py_DECREF(nameobj);
    return module;
}

/* Check API/ABI version
 * Issues a warning on mismatch, which is usually not fatal.
 * Returns 0 if an exception is raised.
 */
static int
check_api_version(const char *name, int module_api_version)
{
    if (module_api_version != PYTHON_API_VERSION && module_api_version != PYTHON_ABI_VERSION) {
        int err;
        err = PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
            "Python C API version mismatch for module %.100s: "
            "This Python has API version %d, module %.100s has version %d.",
             name,
             PYTHON_API_VERSION, name, module_api_version);
        if (err)
            return 0;
    }
    return 1;
}

static int
_add_methods_to_object(PyObject *module, PyObject *name, PyMethodDef *functions)
{
    PyObject *func;
    PyMethodDef *fdef;

    for (fdef = functions; fdef->ml_name != NULL; fdef++) {
        if ((fdef->ml_flags & METH_CLASS) ||
            (fdef->ml_flags & METH_STATIC)) {
            PyErr_SetString(PyExc_ValueError,
                            "module functions cannot set"
                            " METH_CLASS or METH_STATIC");
            return -1;
        }
        func = PyCFunction_NewEx(fdef, (PyObject*)module, name);
        if (func == NULL) {
            return -1;
        }
        _PyObject_SetDeferredRefcount(func);
        if (PyObject_SetAttrString(module, fdef->ml_name, func) != 0) {
            Py_DECREF(func);
            return -1;
        }
        Py_DECREF(func);
    }

    return 0;
}

PyObject *
PyModule_Create2(PyModuleDef* module, int module_api_version)
{
    if (!_PyImport_IsInitialized(_PyInterpreterState_GET())) {
        PyErr_SetString(PyExc_SystemError,
                        "Python import machinery not initialized");
        return NULL;
    }
    return _PyModule_CreateInitialized(module, module_api_version);
}

static void
module_copy_members_from_deflike(
    PyModuleObject *md,
    PyModuleDef *def_like /* not necessarily a valid Python object */)
{
    md->md_state_size = def_like->m_size;
    md->md_state_traverse = def_like->m_traverse;
    md->md_state_clear = def_like->m_clear;
    md->md_state_free = def_like->m_free;
}

PyObject *
_PyModule_CreateInitialized(PyModuleDef* module, int module_api_version)
{
    const char* name;
    PyModuleObject *m;

    if (!PyModuleDef_Init(module))
        return NULL;
    name = module->m_name;
    if (!check_api_version(name, module_api_version)) {
        return NULL;
    }
    if (module->m_slots) {
        PyErr_Format(
            PyExc_SystemError,
            "module %s: PyModule_Create is incompatible with m_slots", name);
        return NULL;
    }
    name = _PyImport_ResolveNameWithPackageContext(name);

    m = (PyModuleObject*)PyModule_New(name);
    if (m == NULL)
        return NULL;

    if (module->m_size > 0) {
        m->md_state = PyMem_Malloc(module->m_size);
        if (!m->md_state) {
            PyErr_NoMemory();
            Py_DECREF(m);
            return NULL;
        }
        memset(m->md_state, 0, module->m_size);
    }

    if (module->m_methods != NULL) {
        if (PyModule_AddFunctions((PyObject *) m, module->m_methods) != 0) {
            Py_DECREF(m);
            return NULL;
        }
    }
    if (module->m_doc != NULL) {
        if (PyModule_SetDocString((PyObject *) m, module->m_doc) != 0) {
            Py_DECREF(m);
            return NULL;
        }
    }
    m->md_token = module;
    m->md_token_is_def = true;
    module_copy_members_from_deflike(m, module);
#ifdef Py_GIL_DISABLED
    m->md_requires_gil = true;
#endif
    return (PyObject*)m;
}

typedef PyObject *(*createfunc_t)(PyObject *, PyModuleDef*);

static PyObject *
module_from_slots_and_spec(
    const PySlot *slots,
    PyObject *spec,
    int module_api_version,
    PyModuleDef* original_def /* NULL if not defined by a def */)
{
    createfunc_t create = NULL;
    PyObject *nameobj;
    PyObject *m = NULL;
    uint64_t multiple_interpreters = (uint64_t)Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED;
    bool requires_gil = true;
    const char *name;
    int ret;
    void *token = NULL;
    _Py_modexecfunc m_exec = NULL;
    PyInterpreterState *interp = _PyInterpreterState_GET();

    nameobj = PyObject_GetAttrString(spec, "name");
    if (nameobj == NULL) {
        return NULL;
    }
    name = PyUnicode_AsUTF8(nameobj);
    if (name == NULL) {
        goto error;
    }

    if (!check_api_version(name, module_api_version)) {
        goto error;
    }

    _PySlotIterator it;

    PyModuleDef _dummy_def = {0};
    PyModuleDef *def_like;
    if (slots) {
        assert(!original_def);
        def_like = &_dummy_def;
         _PySlotIterator_Init(&it, slots, _PySlot_KIND_MOD);
    }
    else {
        assert(original_def);
        def_like = original_def;
         _PySlotIterator_InitLegacy(&it, def_like->m_slots, _PySlot_KIND_MOD);
    }
    it.name = name;

    while (_PySlotIterator_Next(&it)) {
        switch (it.current.sl_id) {
            case Py_slot_invalid:
                goto error;
            case Py_mod_create:
                create = (createfunc_t)it.current.sl_func;
                break;
            case Py_mod_exec:
                if (!original_def) {
                    if (m_exec) {
                        PyErr_Format(
                            PyExc_SystemError,
                            "module %s has multiple Py_mod_exec slots",
                            name);
                        goto error;
                    }
                    m_exec = (_Py_modexecfunc)it.current.sl_func;
                }
                break;
            case Py_mod_multiple_interpreters:
                multiple_interpreters = it.current.sl_uint64;
                break;
            case Py_mod_gil:
                {
                    uint64_t val = it.current.sl_uint64;
                    requires_gil = (val != (uint64_t)Py_MOD_GIL_NOT_USED);
                }
                break;
            case Py_mod_abi:
                if (PyABIInfo_Check(it.current.sl_ptr, name) < 0) {
                    goto error;
                }
                break;
            case Py_mod_token:
                if (original_def && original_def != it.current.sl_ptr) {
                    PyErr_Format(
                        PyExc_SystemError,
                        "module %s: arbitrary Py_mod_token not "
                        "allowed with PyModuleDef",
                        name);
                    goto error;
                }
                token = it.current.sl_ptr;
                break;
            // Common case: Copy a PEP 793 slot to def_like
#define DEF_SLOT_CASE(SLOT, TYPE, SL_MEMBER, MEMBER)                        \
            case SLOT:                                                      \
                do {                                                        \
                    if (original_def) {                                     \
                        TYPE orig_value = (TYPE)original_def->MEMBER;       \
                        TYPE new_value = (TYPE)it.current.SL_MEMBER;        \
                        if (orig_value != new_value) {                      \
                            PyErr_Format(                                   \
                                PyExc_SystemError,                          \
                                "module %s: %s conflicts with "             \
                                "PyModuleDef." #MEMBER,                     \
                                name, _PySlot_GetName(it.current.sl_id));   \
                            goto error;                                     \
                        }                                                   \
                    }                                                       \
                    (def_like->MEMBER) = (TYPE)it.current.SL_MEMBER;        \
                } while (0);                                                \
                break;                                                      \
            /////////////////////////////////////////////////////////////////
            DEF_SLOT_CASE(Py_mod_name, char*, sl_ptr, m_name)
            DEF_SLOT_CASE(Py_mod_doc, char*, sl_ptr, m_doc)
            DEF_SLOT_CASE(Py_mod_state_size, Py_ssize_t, sl_size, m_size)
            DEF_SLOT_CASE(Py_mod_methods, PyMethodDef*, sl_ptr, m_methods)
            DEF_SLOT_CASE(Py_mod_state_traverse,
                          traverseproc, sl_func, m_traverse)
            DEF_SLOT_CASE(Py_mod_state_clear, inquiry, sl_func, m_clear)
            DEF_SLOT_CASE(Py_mod_state_free, freefunc, sl_func, m_free)
#undef DEF_SLOT_CASE
        }
    }
    if (!original_def && !_PySlotIterator_SawSlot(&it, Py_mod_abi)) {
        PyErr_Format(
            PyExc_SystemError,
            "module %s does not define Py_mod_abi,"
            " which is mandatory for modules defined from slots only.",
            name);
        goto error;
    }

#ifdef Py_GIL_DISABLED
    // For modules created directly from slots (not from a def), we enable
    // the GIL here (pairing `_PyEval_EnableGILTransient` with
    // an immediate `_PyImport_EnableGILAndWarn`).
    // For modules created from a def, the caller is responsible for this.
    if (!original_def && requires_gil) {
        PyThreadState *tstate = _PyThreadState_GET();
        if (_PyEval_EnableGILTransient(tstate) < 0) {
            goto error;
        }
        if (_PyImport_EnableGILAndWarn(tstate, nameobj) < 0) {
            goto error;
        }
    }
#endif

    if (def_like->m_size < 0) {
        PyErr_Format(
            PyExc_SystemError,
            "module %s: m_size may not be negative for multi-phase initialization",
            name);
        goto error;
    }

    /* By default, multi-phase init modules are expected
       to work under multiple interpreters. */
    if (multiple_interpreters == (int64_t)(intptr_t)Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED) {
        if (!_Py_IsMainInterpreter(interp)
            && _PyImport_CheckSubinterpIncompatibleExtensionAllowed(name) < 0)
        {
            goto error;
        }
    }
    else if (multiple_interpreters != (int64_t)(intptr_t)Py_MOD_PER_INTERPRETER_GIL_SUPPORTED
             && interp->ceval.own_gil
             && !_Py_IsMainInterpreter(interp)
             && _PyImport_CheckSubinterpIncompatibleExtensionAllowed(name) < 0)
    {
        goto error;
    }

    if (create) {
        m = create(spec, original_def);
        if (m == NULL) {
            if (!PyErr_Occurred()) {
                PyErr_Format(
                    PyExc_SystemError,
                    "creation of module %s failed without setting an exception",
                    name);
            }
            goto error;
        } else {
            if (PyErr_Occurred()) {
                _PyErr_FormatFromCause(
                    PyExc_SystemError,
                    "creation of module %s raised unreported exception",
                    name);
                goto error;
            }
        }
    } else {
        m = PyModule_NewObject(nameobj);
        if (m == NULL) {
            goto error;
        }
    }

    if (PyModule_Check(m)) {
        PyModuleObject *mod = (PyModuleObject*)m;
        mod->md_state = NULL;
        module_copy_members_from_deflike(mod, def_like);
        if (original_def) {
            assert (!token || token == original_def);
            mod->md_token = original_def;
            mod->md_token_is_def = 1;
        }
        else {
            mod->md_token = token;
        }
#ifdef Py_GIL_DISABLED
        mod->md_requires_gil = requires_gil;
#else
        (void)requires_gil;
#endif
        mod->md_exec = m_exec;
    } else {
        if (def_like->m_size > 0 || def_like->m_traverse || def_like->m_clear
            || def_like->m_free)
        {
            PyErr_Format(
                PyExc_SystemError,
                "module %s is not a module object, but requests module state",
                name);
            goto error;
        }
        if (_PySlotIterator_SawSlot(&it, Py_mod_exec)) {
            PyErr_Format(
                PyExc_SystemError,
                "module %s specifies execution slots, but did not create "
                    "a ModuleType instance",
                name);
            goto error;
        }
        if (token) {
            PyErr_Format(
                PyExc_SystemError,
                "module %s specifies a token, but did not create "
                    "a ModuleType instance",
                name);
            goto error;
        }
    }

    if (def_like->m_methods != NULL) {
        ret = _add_methods_to_object(m, nameobj, def_like->m_methods);
        if (ret != 0) {
            goto error;
        }
    }

    if (def_like->m_doc != NULL) {
        ret = PyModule_SetDocString(m, def_like->m_doc);
        if (ret != 0) {
            goto error;
        }
    }

    Py_DECREF(nameobj);
    return m;

error:
    Py_DECREF(nameobj);
    Py_XDECREF(m);
    return NULL;
}

PyObject *
PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_version)
{
    PyModuleDef_Init(def);
    return module_from_slots_and_spec(NULL, spec, module_api_version, def);
}

PyObject *
PyModule_FromSlotsAndSpec(const PySlot *slots, PyObject *spec)
{
    if (!slots) {
        PyErr_SetString(
            PyExc_SystemError,
            "PyModule_FromSlotsAndSpec called with NULL slots");
        return NULL;
    }

    return module_from_slots_and_spec(slots, spec, PYTHON_API_VERSION,
                                      NULL);
}

#ifdef Py_GIL_DISABLED
int
PyUnstable_Module_SetGIL(PyObject *module, void *gil)
{
    bool requires_gil = (gil != Py_MOD_GIL_NOT_USED);
    if (!PyModule_Check(module)) {
        PyErr_BadInternalCall();
        return -1;
    }
    ((PyModuleObject *)module)->md_requires_gil = requires_gil;
    return 0;
}
#endif

static int
run_exec_func(PyObject *module, int (*exec)(PyObject *))
{
    int ret = exec(module);
    if (ret != 0) {
        if (!PyErr_Occurred()) {
            PyErr_Format(
                PyExc_SystemError,
                "execution of %R failed without setting an exception",
                module);
        }
        return -1;
    }
    if (PyErr_Occurred()) {
        _PyErr_FormatFromCause(
            PyExc_SystemError,
            "execution of module %R raised unreported exception",
            module);
        return -1;
    }
    return 0;
}

static int
alloc_state(PyObject *module)
{
    if (!PyModule_Check(module)) {
        PyErr_Format(PyExc_TypeError, "expected module, got %T", module);
        return -1;
    }
    PyModuleObject *md = (PyModuleObject*)module;

    if (md->md_state_size >= 0) {
        if (md->md_state == NULL) {
            /* Always set a state pointer; this serves as a marker to skip
             * multiple initialization (importlib.reload() is no-op) */
            md->md_state = PyMem_Malloc(md->md_state_size);
            if (!md->md_state) {
                PyErr_NoMemory();
                return -1;
            }
            memset(md->md_state, 0, md->md_state_size);
        }
    }
    return 0;
}

int
PyModule_Exec(PyObject *module)
{
    if (alloc_state(module) < 0) {
        return -1;
    }
    PyModuleObject *md = (PyModuleObject*)module;
    if (md->md_exec) {
        assert(!md->md_token_is_def);
        return run_exec_func(module, md->md_exec);
    }

    PyModuleDef *def = _PyModule_GetDefOrNull(module);
    if (def) {
        return PyModule_ExecDef(module, def);
    }
    return 0;
}

int
PyModule_ExecDef(PyObject *module, PyModuleDef *def)
{
    if (alloc_state(module) < 0) {
        return -1;
    }

    assert(PyModule_Check(module));

    if (def->m_slots == NULL) {
        return 0;
    }

    _PySlotIterator it;
    _PySlotIterator_InitLegacy(&it, def->m_slots, _PySlot_KIND_MOD);
    while (_PySlotIterator_Next(&it)) {
        _Py_modexecfunc func;
        switch (it.current.sl_id) {
            case Py_slot_invalid:
                return -1;
            case Py_mod_exec:
                func = (_Py_modexecfunc)it.current.sl_func;
                if (run_exec_func(module, func) < 0) {
                    return -1;
                }
                break;
        }
    }
    return 0;
}

int
PyModule_AddFunctions(PyObject *m, PyMethodDef *functions)
{
    int res;
    PyObject *name = PyModule_GetNameObject(m);
    if (name == NULL) {
        return -1;
    }

    res = _add_methods_to_object(m, name, functions);
    Py_DECREF(name);
    return res;
}

int
PyModule_SetDocString(PyObject *m, const char *doc)
{
    PyObject *v;

    v = PyUnicode_FromString(doc);
    if (v == NULL || PyObject_SetAttr(m, &_Py_ID(__doc__), v) != 0) {
        Py_XDECREF(v);
        return -1;
    }
    Py_DECREF(v);
    return 0;
}

PyObject *
PyModule_GetDict(PyObject *m)
{
    if (!PyModule_Check(m)) {
        PyErr_BadInternalCall();
        return NULL;
    }
    return _PyModule_GetDict(m);  // borrowed reference
}

int
PyModule_GetStateSize(PyObject *m, Py_ssize_t *size_p)
{
    *size_p = -1;
    if (!PyModule_Check(m)) {
        PyErr_Format(PyExc_TypeError, "expected module, got %T", m);
        return -1;
    }
    PyModuleObject *mod = (PyModuleObject *)m;
    *size_p = mod->md_state_size;
    return 0;
}

int
PyModule_GetToken_DuringGC(PyObject *m, void **token_p)
{
    *token_p = NULL;
    if (!PyModule_Check(m)) {
        return -1;
    }
    *token_p = _PyModule_GetToken(m);
    return 0;
}

int
PyModule_GetToken(PyObject *m, void **token_p)
{
    *token_p = NULL;
    if (!PyModule_Check(m)) {
        PyErr_Format(PyExc_TypeError, "expected module, got %T", m);
        return -1;
    }
    *token_p = _PyModule_GetToken(m);
    return 0;
}

PyObject*
PyModule_GetNameObject(PyObject *mod)
{
    if (!PyModule_Check(mod)) {
        PyErr_BadArgument();
        return NULL;
    }
    PyObject *dict = ((PyModuleObject *)mod)->md_dict;  // borrowed reference
    if (dict == NULL || !PyDict_Check(dict)) {
        goto error;
    }
    PyObject *name;
    if (PyDict_GetItemRef(dict, &_Py_ID(__name__), &name) <= 0) {
        // error or not found
        goto error;
    }
    if (!PyUnicode_Check(name)) {
        Py_DECREF(name);
        goto error;
    }
    return name;

error:
    if (!PyErr_Occurred()) {
        PyErr_SetString(PyExc_SystemError, "nameless module");
    }
    return NULL;
}

const char *
PyModule_GetName(PyObject *m)
{
    PyObject *name = PyModule_GetNameObject(m);
    if (name == NULL) {
        return NULL;
    }
    assert(Py_REFCNT(name) >= 2);
    Py_DECREF(name);   /* module dict has still a reference */
    return PyUnicode_AsUTF8(name);
}

PyObject*
_PyModule_GetFilenameObject(PyObject *mod)
{
    // We return None to indicate "not found" or "bogus".
    if (!PyModule_Check(mod)) {
        PyErr_BadArgument();
        return NULL;
    }
    PyObject *dict = ((PyModuleObject *)mod)->md_dict;  // borrowed reference
    if (dict == NULL) {
        // The module has been tampered with.
        Py_RETURN_NONE;
    }
    PyObject *fileobj;
    int res = PyDict_GetItemRef(dict, &_Py_ID(__file__), &fileobj);
    if (res < 0) {
        return NULL;
    }
    if (res == 0) {
        // __file__ isn't set.  There are several reasons why this might
        // be so, most of them valid reasons.  If it's the __main__
        // module then we're running the REPL or with -c.  Otherwise
        // it's a namespace package or other module with a loader that
        // isn't disk-based.  It could also be that a user created
        // a module manually but without manually setting __file__.
        Py_RETURN_NONE;
    }
    if (!PyUnicode_Check(fileobj)) {
        Py_DECREF(fileobj);
        Py_RETURN_NONE;
    }
    return fileobj;
}

PyObject*
PyModule_GetFilenameObject(PyObject *mod)
{
    PyObject *fileobj = _PyModule_GetFilenameObject(mod);
    if (fileobj == NULL) {
        return NULL;
    }
    if (fileobj == Py_None) {
        PyErr_SetString(PyExc_SystemError, "module filename missing");
        return NULL;
    }
    return fileobj;
}

const char *
PyModule_GetFilename(PyObject *m)
{
    PyObject *fileobj;
    const char *utf8;
    fileobj = PyModule_GetFilenameObject(m);
    if (fileobj == NULL)
        return NULL;
    utf8 = PyUnicode_AsUTF8(fileobj);
    Py_DECREF(fileobj);   /* module dict has still a reference */
    return utf8;
}

Py_ssize_t
_PyModule_GetFilenameUTF8(PyObject *mod, char *buffer, Py_ssize_t maxlen)
{
    // We "return" an empty string for an invalid module
    // and for a missing, empty, or invalid filename.
    assert(maxlen >= 0);
    Py_ssize_t size = -1;
    PyObject *filenameobj = _PyModule_GetFilenameObject(mod);
    if (filenameobj == NULL) {
        return -1;
    }
    if (filenameobj == Py_None) {
        // It is missing or invalid.
        buffer[0] = '\0';
        size = 0;
    }
    else {
        const char *filename = PyUnicode_AsUTF8AndSize(filenameobj, &size);
        if (filename == NULL) {
            Py_DECREF(filenameobj);
            return -1;
        }
        assert(size >= 0);
        if (size > maxlen) {
            size = -1;
            PyErr_SetString(PyExc_ValueError, "__file__ too long");
        }
        else {
            (void)strcpy(buffer, filename);
        }
    }
    Py_DECREF(filenameobj);
    return size;
}

PyModuleDef*
PyModule_GetDef(PyObject* m)
{
    if (!PyModule_Check(m)) {
        PyErr_BadArgument();
        return NULL;
    }
    return _PyModule_GetDefOrNull(m);
}

void*
PyModule_GetState_DuringGC(PyObject* m)
{
    if (!PyModule_Check(m)) {
        return NULL;
    }
    return _PyModule_GetState(m);
}

void*
PyModule_GetState(PyObject* m)
{
    if (!PyModule_Check(m)) {
        PyErr_BadArgument();
        return NULL;
    }
    return _PyModule_GetState(m);
}

void
_PyModule_Clear(PyObject *m)
{
    PyObject *d = ((PyModuleObject *)m)->md_dict;
    if (d != NULL)
        _PyModule_ClearDict(d);
}

void
_PyModule_ClearDict(PyObject *d)
{
    /* To make the execution order of destructors for global
       objects a bit more predictable, we first zap all objects
       whose name starts with a single underscore, before we clear
       the entire dictionary.  We zap them by replacing them with
       None, rather than deleting them from the dictionary, to
       avoid rehashing the dictionary (to some extent). */

    Py_ssize_t pos;
    PyObject *key, *value;

    int verbose = _Py_GetConfig()->verbose;

    /* First, clear only names starting with a single underscore */
    pos = 0;
    while (PyDict_Next(d, &pos, &key, &value)) {
        if (value != Py_None && PyUnicode_Check(key)) {
            if (PyUnicode_READ_CHAR(key, 0) == '_' &&
                PyUnicode_READ_CHAR(key, 1) != '_') {
                if (verbose > 1) {
                    const char *s = PyUnicode_AsUTF8(key);
                    if (s != NULL)
                        PySys_WriteStderr("#   clear[1] %s\n", s);
                    else
                        PyErr_Clear();
                }
                if (PyDict_SetItem(d, key, Py_None) != 0) {
                    PyErr_FormatUnraisable("Exception ignored while "
                                           "clearing module dict");
                }
            }
        }
    }

    /* Next, clear all names except for __builtins__ */
    pos = 0;
    while (PyDict_Next(d, &pos, &key, &value)) {
        if (value != Py_None && PyUnicode_Check(key)) {
            if (PyUnicode_READ_CHAR(key, 0) != '_' ||
                !_PyUnicode_EqualToASCIIString(key, "__builtins__"))
            {
                if (verbose > 1) {
                    const char *s = PyUnicode_AsUTF8(key);
                    if (s != NULL)
                        PySys_WriteStderr("#   clear[2] %s\n", s);
                    else
                        PyErr_Clear();
                }
                if (PyDict_SetItem(d, key, Py_None) != 0) {
                    PyErr_FormatUnraisable("Exception ignored while "
                                           "clearing module dict");
                }
            }
        }
    }

    /* Note: we leave __builtins__ in place, so that destructors
       of non-global objects defined in this module can still use
       builtins, in particularly 'None'. */

}

/*[clinic input]
class module "PyModuleObject *" "&PyModule_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3e35d4f708ecb6af]*/

#include "clinic/moduleobject.c.h"

/* Methods */

/*[clinic input]
module.__init__
    name: unicode
    doc: object = None

Create a module object.

The name must be a string; the optional doc argument can have any type.
[clinic start generated code]*/

static int
module___init___impl(PyModuleObject *self, PyObject *name, PyObject *doc)
/*[clinic end generated code: output=e7e721c26ce7aad7 input=57f9e177401e5e1e]*/
{
    return module_init_dict(self, self->md_dict, name, doc);
}

static void
module_dealloc(PyObject *self)
{
    PyModuleObject *m = _PyModule_CAST(self);

    PyObject_GC_UnTrack(m);

    int verbose = _Py_GetConfig()->verbose;
    if (verbose && m->md_name) {
        PySys_FormatStderr("# destroy %U\n", m->md_name);
    }
    FT_CLEAR_WEAKREFS(self, m->md_weaklist);

    assert_def_missing_or_redundant(m);
    /* bpo-39824: Don't call m_free() if m_size > 0 and md_state=NULL */
    if (m->md_state_free && (m->md_state_size <= 0 || m->md_state != NULL))
    {
        m->md_state_free(m);
    }

    Py_XDECREF(m->md_dict);
    Py_XDECREF(m->md_name);
    if (m->md_state != NULL) {
        PyMem_Free(m->md_state);
    }
    Py_TYPE(m)->tp_free((PyObject *)m);
}

static PyObject *
module_repr(PyObject *self)
{
    PyModuleObject *m = _PyModule_CAST(self);
    PyInterpreterState *interp = _PyInterpreterState_GET();
    return _PyImport_ImportlibModuleRepr(interp, (PyObject *)m);
}

/* Check if the "_initializing" attribute of the module spec is set to true.
 */
int
_PyModuleSpec_IsInitializing(PyObject *spec)
{
    if (spec == NULL) {
        return 0;
    }
    PyObject *value;
    int rc = PyObject_GetOptionalAttr(spec, &_Py_ID(_initializing), &value);
    if (rc > 0) {
        rc = PyObject_IsTrue(value);
        Py_DECREF(value);
    }
    return rc;
}

/* Check if the submodule name is in the "_uninitialized_submodules" attribute
   of the module spec.
 */
int
_PyModuleSpec_IsUninitializedSubmodule(PyObject *spec, PyObject *name)
{
    if (spec == NULL) {
         return 0;
    }

    PyObject *value;
    int rc = PyObject_GetOptionalAttr(spec, &_Py_ID(_uninitialized_submodules), &value);
    if (rc > 0) {
        rc = PySequence_Contains(value, name);
        Py_DECREF(value);
    }
    return rc;
}

int
_PyModuleSpec_GetFileOrigin(PyObject *spec, PyObject **p_origin)
{
    PyObject *has_location = NULL;
    int rc = PyObject_GetOptionalAttr(spec, &_Py_ID(has_location), &has_location);
    if (rc <= 0) {
        return rc;
    }
    // If origin is not a location, or doesn't exist, or is not a str, we could consider falling
    // back to module.__file__. But the cases in which module.__file__ is not __spec__.origin
    // are cases in which we probably shouldn't be guessing.
    rc = PyObject_IsTrue(has_location);
    Py_DECREF(has_location);
    if (rc <= 0) {
        return rc;
    }
    // has_location is true, so origin is a location
    PyObject *origin = NULL;
    rc = PyObject_GetOptionalAttr(spec, &_Py_ID(origin), &origin);
    if (rc <= 0) {
        return rc;
    }
    assert(origin != NULL);
    if (!PyUnicode_Check(origin)) {
        Py_DECREF(origin);
        return 0;
    }
    *p_origin = origin;
    return 1;
}

int
_PyModule_IsPossiblyShadowing(PyObject *origin)
{
    int result = 0;
    wchar_t *root = NULL;
    wchar_t *sys_path_0_buf = NULL;

    // origin must be a unicode subtype
    // Returns 1 if the module at origin could be shadowing a module of the
    // same name later in the module search path. The condition we check is basically:
    // root = os.path.dirname(origin.removesuffix(os.sep + "__init__.py"))
    // return not sys.flags.safe_path and root == (sys.path[0] or os.getcwd())
    // Returns 0 otherwise (or if we aren't sure)
    // Returns -1 if an error occurred that should be propagated
    if (origin == NULL) {
        return 0;
    }

    // not sys.flags.safe_path
    const PyConfig *config = _Py_GetConfig();
    if (config->safe_path) {
        return 0;
    }

    // root = os.path.dirname(origin.removesuffix(os.sep + "__init__.py"))
    root = PyUnicode_AsWideCharString(origin, NULL);
    if (root == NULL) {
        return -1;
    }

    wchar_t *sep = wcsrchr(root, SEP);
    if (sep == NULL) {
        goto done;
    }
    // If it's a package then we need to look one directory further up
    if (wcscmp(sep + 1, L"__init__.py") == 0) {
        *sep = L'\0';
        sep = wcsrchr(root, SEP);
        if (sep == NULL) {
            goto done;
        }
    }
    *sep = L'\0';

    // sys.path[0] or os.getcwd()
    wchar_t *sys_path_0 = config->sys_path_0;
    if (!sys_path_0) {
        goto done;
    }

    if (sys_path_0[0] == L'\0') {
        // if sys.path[0] == "", treat it as if it were the current directory
        sys_path_0_buf = PyMem_Malloc(MAXPATHLEN * sizeof(wchar_t));
        if (sys_path_0_buf == NULL) {
            PyErr_NoMemory();
            result = -1;
            goto done;
        }
        if (!_Py_wgetcwd(sys_path_0_buf, MAXPATHLEN)) {
            // If we failed to getcwd, don't raise an exception and instead
            // let the caller proceed assuming no shadowing
            goto done;
        }
        sys_path_0 = sys_path_0_buf;
    }

    result = (wcscmp(sys_path_0, root) == 0);

done:
    PyMem_Free(root);
    PyMem_Free(sys_path_0_buf);
    return result;
}

static int
module_get_resolved_dict_item(PyObject *dict, PyObject *name, PyObject **result)
{
    int rc = PyDict_GetItemRef(dict, name, result);
    if (rc <= 0 || !PyLazyImport_CheckExact(*result)) {
        return rc;
    }
    PyThreadState *tstate = PyThreadState_GET();
    if (_PyLazyImport_IsResolving(tstate, *result)) {
        Py_CLEAR(*result);
        return 0;
    }
    PyObject *value = _PyLazyImport_Reify(tstate, *result, name, dict);
    Py_SETREF(*result, value);
    return value == NULL ? -1 : 1;
}

PyObject*
_Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress)
{
    // When suppress=1, this function suppresses AttributeError.
    PyObject *attr, *mod_name, *getattr;
    attr = _PyObject_GenericGetAttrWithDict((PyObject *)m, name, NULL, suppress);
    if (attr == NULL) {
        if (suppress == 1) {
            if (PyErr_Occurred()) {
                // pass up non-AttributeError exception
                return NULL;
            }
        }
        else {
            if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
                // pass up non-AttributeError exception
                return NULL;
            }
            PyErr_Clear();
        }
        assert(m->md_dict != NULL);
        int recheck_dict;
        attr = _PyImport_TryLoadLazySubmodule((PyObject *)m, name, suppress,
                                             &recheck_dict);
        if (attr != NULL || PyErr_Occurred()) {
            return attr;
        }
        // A concurrent load may have bound the child and removed its pending
        // registration after our initial dictionary lookup.
        if (recheck_dict) {
            if (Py_TYPE(m) != &PyModule_Type) {
                PyObject *descr = _PyType_LookupRef(Py_TYPE(m), name);
                if (descr != NULL) {
                    // Preserve the fallback after a descriptor raised.
                    recheck_dict = Py_TYPE(descr)->tp_descr_get == NULL;
                    Py_DECREF(descr);
                }
            }
            if (recheck_dict &&
                PyDict_GetItemRef(m->md_dict, name, &attr) < 0) {
                return NULL;
            }
        }
    }
    if (attr) {
        if (PyLazyImport_CheckExact(attr)) {
            PyThreadState *tstate = PyThreadState_GET();
            if (suppress && _PyLazyImport_IsResolving(tstate, attr)) {
                // Only direct reentry means this attribute is unavailable.
                Py_DECREF(attr);
                return NULL;
            }
            PyObject *new_value = _PyLazyImport_Reify(
                tstate, attr, name, m->md_dict);
            Py_DECREF(attr);
            return new_value;
        }
        return attr;
    }
    if (module_get_resolved_dict_item(
            m->md_dict, &_Py_ID(__getattr__), &getattr) < 0) {
        return NULL;
    }
    if (getattr) {
        PyObject *result = PyObject_CallOneArg(getattr, name);
        if (result == NULL && suppress == 1 && PyErr_ExceptionMatches(PyExc_AttributeError)) {
            // suppress AttributeError
            PyErr_Clear();
        }
        Py_DECREF(getattr);
        return result;
    }

    // The attribute was not found.  We make a best effort attempt at a useful error message,
    // but only if we're not suppressing AttributeError.
    if (suppress == 1) {
        return NULL;
    }
    if (PyDict_GetItemRef(m->md_dict, &_Py_ID(__name__), &mod_name) < 0) {
        return NULL;
    }
    if (!mod_name || !PyUnicode_Check(mod_name)) {
        Py_XDECREF(mod_name);
        PyErr_Format(PyExc_AttributeError,
                    "module has no attribute '%U'", name);
        return NULL;
    }
    PyObject *spec;
    if (PyDict_GetItemRef(m->md_dict, &_Py_ID(__spec__), &spec) < 0) {
        Py_DECREF(mod_name);
        return NULL;
    }
    if (spec == NULL) {
        PyErr_Format(PyExc_AttributeError,
                     "module '%U' has no attribute '%U'",
                     mod_name, name);
        Py_DECREF(mod_name);
        return NULL;
    }

    PyObject *origin = NULL;
    if (_PyModuleSpec_GetFileOrigin(spec, &origin) < 0) {
        goto done;
    }

    int is_possibly_shadowing = _PyModule_IsPossiblyShadowing(origin);
    if (is_possibly_shadowing < 0) {
        goto done;
    }
    int is_possibly_shadowing_stdlib = 0;
    if (is_possibly_shadowing) {
        PyObject *stdlib_modules;
        if (PySys_GetOptionalAttrString("stdlib_module_names", &stdlib_modules) < 0) {
            goto done;
        }
        if (stdlib_modules && PyAnySet_Check(stdlib_modules)) {
            is_possibly_shadowing_stdlib = PySet_Contains(stdlib_modules, mod_name);
            if (is_possibly_shadowing_stdlib < 0) {
                Py_DECREF(stdlib_modules);
                goto done;
            }
        }
        Py_XDECREF(stdlib_modules);
    }

    if (is_possibly_shadowing_stdlib) {
        assert(origin);
        PyErr_Format(PyExc_AttributeError,
                    "module '%U' has no attribute '%U' "
                    "(consider renaming '%U' since it has the same "
                    "name as the standard library module named '%U' "
                    "and prevents importing that standard library module)",
                    mod_name, name, origin, mod_name);
    }
    else {
        int rc = _PyModuleSpec_IsInitializing(spec);
        if (rc < 0) {
            goto done;
        }
        else if (rc > 0) {
            if (is_possibly_shadowing) {
                assert(origin);
                // For non-stdlib modules, only mention the possibility of
                // shadowing if the module is being initialized.
                PyErr_Format(PyExc_AttributeError,
                            "module '%U' has no attribute '%U' "
                            "(consider renaming '%U' if it has the same name "
                            "as a library you intended to import)",
                            mod_name, name, origin);
            }
            else if (origin) {
                PyErr_Format(PyExc_AttributeError,
                            "partially initialized "
                            "module '%U' from '%U' has no attribute '%U' "
                            "(most likely due to a circular import)",
                            mod_name, origin, name);
            }
            else {
                PyErr_Format(PyExc_AttributeError,
                            "partially initialized "
                            "module '%U' has no attribute '%U' "
                            "(most likely due to a circular import)",
                            mod_name, name);
            }
        }
        else {
            assert(rc == 0);
            rc = _PyModuleSpec_IsUninitializedSubmodule(spec, name);
            if (rc > 0) {
                PyErr_Format(PyExc_AttributeError,
                            "cannot access submodule '%U' of module '%U' "
                            "(most likely due to a circular import)",
                            name, mod_name);
            }
            else if (rc == 0) {
                PyErr_Format(PyExc_AttributeError,
                            "module '%U' has no attribute '%U'",
                            mod_name, name);
            }
        }
    }

done:
    Py_XDECREF(origin);
    Py_DECREF(spec);
    Py_DECREF(mod_name);
    return NULL;
}


PyObject*
_Py_module_getattro(PyObject *self, PyObject *name)
{
    PyModuleObject *m = _PyModule_CAST(self);
    return _Py_module_getattro_impl(m, name, 0);
}

static int
module_traverse(PyObject *self, visitproc visit, void *arg)
{
    PyModuleObject *m = _PyModule_CAST(self);

    assert_def_missing_or_redundant(m);
    /* bpo-39824: Don't call m_traverse() if m_size > 0 and md_state=NULL */
    if (m->md_state_traverse && (m->md_state_size <= 0 || m->md_state != NULL))
    {
        int res = m->md_state_traverse((PyObject*)m, visit, arg);
        if (res)
            return res;
    }

    Py_VISIT(m->md_dict);
    return 0;
}

static int
module_clear(PyObject *self)
{
    PyModuleObject *m = _PyModule_CAST(self);

    assert_def_missing_or_redundant(m);
    /* bpo-39824: Don't call m_clear() if m_size > 0 and md_state=NULL */
    if (m->md_state_clear && (m->md_state_size <= 0 || m->md_state != NULL))
    {
        int res = m->md_state_clear((PyObject*)m);
        if (PyErr_Occurred()) {
            PyErr_FormatUnraisable("Exception ignored in m_clear of module%s%V",
                                   m->md_name ? " " : "",
                                   m->md_name, "");
        }
        if (res) {
            return res;
        }
    }
    Py_CLEAR(m->md_dict);
    return 0;
}

static PyObject *
module_dir(PyObject *self, PyObject *args)
{
    PyObject *result = NULL;
    PyObject *dict;
    if (PyModule_CheckExact(self)) {
        dict = Py_NewRef(((PyModuleObject *)self)->md_dict);
    } else {
        dict = PyObject_GetAttr(self, &_Py_ID(__dict__));
    }

    if (dict != NULL) {
        if (PyDict_Check(dict)) {
            PyObject *dirfunc;
            int rc = module_get_resolved_dict_item(
                dict, &_Py_ID(__dir__), &dirfunc);
            if (rc > 0) {
                result = _PyObject_CallNoArgs(dirfunc);
                Py_DECREF(dirfunc);
            }
            else if (rc == 0) {
                result = PyDict_Keys(dict);
            }
        }
        else {
            PyErr_Format(PyExc_TypeError, "<module>.__dict__ is not a dictionary");
        }
    }

    Py_XDECREF(dict);
    return result;
}

static PyMethodDef module_methods[] = {
    {"__dir__", module_dir, METH_NOARGS,
     PyDoc_STR("__dir__() -> list\nspecialized dir() implementation")},
    {0}
};

static PyObject *
module_load_dict(PyModuleObject *m)
{
    PyObject *dict = PyObject_GetAttr((PyObject *)m, &_Py_ID(__dict__));
    if (dict == NULL) {
        return NULL;
    }
    if (!PyDict_Check(dict)) {
        PyErr_Format(PyExc_TypeError, "<module>.__dict__ is not a dictionary");
        Py_DECREF(dict);
        return NULL;
    }
    return dict;
}

static PyObject *
module_get_annotate(PyObject *self, void *Py_UNUSED(ignored))
{
    PyModuleObject *m = _PyModule_CAST(self);

    PyObject *dict = module_load_dict(m);
    if (dict == NULL) {
        return NULL;
    }

    PyObject *annotate;
    if (PyDict_GetItemRef(dict, &_Py_ID(__annotate__), &annotate) == 0) {
        annotate = Py_None;
        if (PyDict_SetItem(dict, &_Py_ID(__annotate__), annotate) == -1) {
            Py_CLEAR(annotate);
        }
    }
    Py_DECREF(dict);
    return annotate;
}

static int
module_set_annotate(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
{
    PyModuleObject *m = _PyModule_CAST(self);
    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError, "cannot delete __annotate__ attribute");
        return -1;
    }

    PyObject *dict = module_load_dict(m);
    if (dict == NULL) {
        return -1;
    }

    if (!Py_IsNone(value) && !PyCallable_Check(value)) {
        PyErr_SetString(PyExc_TypeError, "__annotate__ must be callable or None");
        Py_DECREF(dict);
        return -1;
    }

    if (PyDict_SetItem(dict, &_Py_ID(__annotate__), value) == -1) {
        Py_DECREF(dict);
        return -1;
    }
    if (!Py_IsNone(value)) {
        if (PyDict_Pop(dict, &_Py_ID(__annotations__), NULL) == -1) {
            Py_DECREF(dict);
            return -1;
        }
    }
    Py_DECREF(dict);
    return 0;
}

static PyObject *
module_get_annotations(PyObject *self, void *Py_UNUSED(ignored))
{
    PyModuleObject *m = _PyModule_CAST(self);

    PyObject *dict = module_load_dict(m);
    if (dict == NULL) {
        return NULL;
    }

    PyObject *annotations;
    if (PyDict_GetItemRef(dict, &_Py_ID(__annotations__), &annotations) == 0) {
        PyObject *spec;
        if (PyDict_GetItemRef(m->md_dict, &_Py_ID(__spec__), &spec) < 0) {
            Py_DECREF(dict);
            return NULL;
        }
        bool is_initializing = false;
        if (spec != NULL) {
            int rc = _PyModuleSpec_IsInitializing(spec);
            if (rc < 0) {
                Py_DECREF(spec);
                Py_DECREF(dict);
                return NULL;
            }
            Py_DECREF(spec);
            if (rc) {
                is_initializing = true;
            }
        }

        PyObject *annotate;
        int annotate_result = PyDict_GetItemRef(dict, &_Py_ID(__annotate__), &annotate);
        if (annotate_result < 0) {
            Py_DECREF(dict);
            return NULL;
        }
        if (annotate_result == 1 && PyCallable_Check(annotate)) {
            PyObject *one = _PyLong_GetOne();
            annotations = _PyObject_CallOneArg(annotate, one);
            if (annotations == NULL) {
                Py_DECREF(annotate);
                Py_DECREF(dict);
                return NULL;
            }
            if (!PyDict_Check(annotations)) {
                PyErr_Format(PyExc_TypeError,
                             "__annotate__() must return a dict, not %T",
                             annotations);
                Py_DECREF(annotate);
                Py_DECREF(annotations);
                Py_DECREF(dict);
                return NULL;
            }
        }
        else {
            annotations = PyDict_New();
        }
        Py_XDECREF(annotate);
        // Do not cache annotations if the module is still initializing
        if (annotations && !is_initializing) {
            int result = PyDict_SetItem(
                    dict, &_Py_ID(__annotations__), annotations);
            if (result) {
                Py_CLEAR(annotations);
            }
        }
    }
    Py_DECREF(dict);
    return annotations;
}

static int
module_set_annotations(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
{
    PyModuleObject *m = _PyModule_CAST(self);

    PyObject *dict = module_load_dict(m);
    if (dict == NULL) {
        return -1;
    }

    int ret = -1;
    if (value != NULL) {
        /* set */
        ret = PyDict_SetItem(dict, &_Py_ID(__annotations__), value);
    }
    else {
        /* delete */
        ret = PyDict_Pop(dict, &_Py_ID(__annotations__), NULL);
        if (ret == 0) {
            PyErr_SetObject(PyExc_AttributeError, &_Py_ID(__annotations__));
            ret = -1;
        }
        else if (ret > 0) {
            ret = 0;
        }
    }
    if (ret == 0 && PyDict_Pop(dict, &_Py_ID(__annotate__), NULL) < 0) {
        ret = -1;
    }

    Py_DECREF(dict);
    return ret;
}

static PyGetSetDef module_getsets[] = {
    {"__annotations__", module_get_annotations, module_set_annotations},
    {"__annotate__", module_get_annotate, module_set_annotate},
    {NULL}
};

PyTypeObject PyModule_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "module",                                   /* tp_name */
    sizeof(PyModuleObject),                     /* tp_basicsize */
    0,                                          /* tp_itemsize */
    module_dealloc,                             /* tp_dealloc */
    0,                                          /* tp_vectorcall_offset */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_as_async */
    module_repr,                                /* tp_repr */
    0,                                          /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    _Py_module_getattro,                        /* tp_getattro */
    PyObject_GenericSetAttr,                    /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        Py_TPFLAGS_BASETYPE,                    /* tp_flags */
    module___init____doc__,                     /* tp_doc */
    module_traverse,                            /* tp_traverse */
    module_clear,                               /* tp_clear */
    0,                                          /* tp_richcompare */
    offsetof(PyModuleObject, md_weaklist),      /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    module_methods,                             /* tp_methods */
    module_members,                             /* tp_members */
    module_getsets,                             /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    offsetof(PyModuleObject, md_dict),          /* tp_dictoffset */
    module___init__,                            /* tp_init */
    0,                                          /* tp_alloc */
    new_module,                                 /* tp_new */
    PyObject_GC_Del,                            /* tp_free */
};
