xref: /third_party/python/Objects/moduleobject.c (revision 7db96d56)
17db96d56Sopenharmony_ci
27db96d56Sopenharmony_ci/* Module object implementation */
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci#include "Python.h"
57db96d56Sopenharmony_ci#include "pycore_call.h"          // _PyObject_CallNoArgs()
67db96d56Sopenharmony_ci#include "pycore_interp.h"        // PyInterpreterState.importlib
77db96d56Sopenharmony_ci#include "pycore_object.h"        // _PyType_AllocNoTrack
87db96d56Sopenharmony_ci#include "pycore_pystate.h"       // _PyInterpreterState_GET()
97db96d56Sopenharmony_ci#include "pycore_moduleobject.h"  // _PyModule_GetDef()
107db96d56Sopenharmony_ci#include "structmember.h"         // PyMemberDef
117db96d56Sopenharmony_ci
127db96d56Sopenharmony_cistatic Py_ssize_t max_module_number;
137db96d56Sopenharmony_ci
147db96d56Sopenharmony_cistatic PyMemberDef module_members[] = {
157db96d56Sopenharmony_ci    {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
167db96d56Sopenharmony_ci    {0}
177db96d56Sopenharmony_ci};
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ciPyTypeObject PyModuleDef_Type = {
217db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
227db96d56Sopenharmony_ci    "moduledef",                                /* tp_name */
237db96d56Sopenharmony_ci    sizeof(PyModuleDef),                        /* tp_basicsize */
247db96d56Sopenharmony_ci    0,                                          /* tp_itemsize */
257db96d56Sopenharmony_ci};
267db96d56Sopenharmony_ci
277db96d56Sopenharmony_ci
287db96d56Sopenharmony_ciint
297db96d56Sopenharmony_ci_PyModule_IsExtension(PyObject *obj)
307db96d56Sopenharmony_ci{
317db96d56Sopenharmony_ci    if (!PyModule_Check(obj)) {
327db96d56Sopenharmony_ci        return 0;
337db96d56Sopenharmony_ci    }
347db96d56Sopenharmony_ci    PyModuleObject *module = (PyModuleObject*)obj;
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_ci    PyModuleDef *def = module->md_def;
377db96d56Sopenharmony_ci    return (def != NULL && def->m_methods != NULL);
387db96d56Sopenharmony_ci}
397db96d56Sopenharmony_ci
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ciPyObject*
427db96d56Sopenharmony_ciPyModuleDef_Init(PyModuleDef* def)
437db96d56Sopenharmony_ci{
447db96d56Sopenharmony_ci    assert(PyModuleDef_Type.tp_flags & Py_TPFLAGS_READY);
457db96d56Sopenharmony_ci    if (def->m_base.m_index == 0) {
467db96d56Sopenharmony_ci        max_module_number++;
477db96d56Sopenharmony_ci        Py_SET_REFCNT(def, 1);
487db96d56Sopenharmony_ci        Py_SET_TYPE(def, &PyModuleDef_Type);
497db96d56Sopenharmony_ci        def->m_base.m_index = max_module_number;
507db96d56Sopenharmony_ci    }
517db96d56Sopenharmony_ci    return (PyObject*)def;
527db96d56Sopenharmony_ci}
537db96d56Sopenharmony_ci
547db96d56Sopenharmony_cistatic int
557db96d56Sopenharmony_cimodule_init_dict(PyModuleObject *mod, PyObject *md_dict,
567db96d56Sopenharmony_ci                 PyObject *name, PyObject *doc)
577db96d56Sopenharmony_ci{
587db96d56Sopenharmony_ci    assert(md_dict != NULL);
597db96d56Sopenharmony_ci    if (doc == NULL)
607db96d56Sopenharmony_ci        doc = Py_None;
617db96d56Sopenharmony_ci
627db96d56Sopenharmony_ci    if (PyDict_SetItem(md_dict, &_Py_ID(__name__), name) != 0)
637db96d56Sopenharmony_ci        return -1;
647db96d56Sopenharmony_ci    if (PyDict_SetItem(md_dict, &_Py_ID(__doc__), doc) != 0)
657db96d56Sopenharmony_ci        return -1;
667db96d56Sopenharmony_ci    if (PyDict_SetItem(md_dict, &_Py_ID(__package__), Py_None) != 0)
677db96d56Sopenharmony_ci        return -1;
687db96d56Sopenharmony_ci    if (PyDict_SetItem(md_dict, &_Py_ID(__loader__), Py_None) != 0)
697db96d56Sopenharmony_ci        return -1;
707db96d56Sopenharmony_ci    if (PyDict_SetItem(md_dict, &_Py_ID(__spec__), Py_None) != 0)
717db96d56Sopenharmony_ci        return -1;
727db96d56Sopenharmony_ci    if (PyUnicode_CheckExact(name)) {
737db96d56Sopenharmony_ci        Py_INCREF(name);
747db96d56Sopenharmony_ci        Py_XSETREF(mod->md_name, name);
757db96d56Sopenharmony_ci    }
767db96d56Sopenharmony_ci
777db96d56Sopenharmony_ci    return 0;
787db96d56Sopenharmony_ci}
797db96d56Sopenharmony_ci
807db96d56Sopenharmony_cistatic PyModuleObject *
817db96d56Sopenharmony_cinew_module_notrack(PyTypeObject *mt)
827db96d56Sopenharmony_ci{
837db96d56Sopenharmony_ci    PyModuleObject *m;
847db96d56Sopenharmony_ci    m = (PyModuleObject *)_PyType_AllocNoTrack(mt, 0);
857db96d56Sopenharmony_ci    if (m == NULL)
867db96d56Sopenharmony_ci        return NULL;
877db96d56Sopenharmony_ci    m->md_def = NULL;
887db96d56Sopenharmony_ci    m->md_state = NULL;
897db96d56Sopenharmony_ci    m->md_weaklist = NULL;
907db96d56Sopenharmony_ci    m->md_name = NULL;
917db96d56Sopenharmony_ci    m->md_dict = PyDict_New();
927db96d56Sopenharmony_ci    if (m->md_dict != NULL) {
937db96d56Sopenharmony_ci        return m;
947db96d56Sopenharmony_ci    }
957db96d56Sopenharmony_ci    Py_DECREF(m);
967db96d56Sopenharmony_ci    return NULL;
977db96d56Sopenharmony_ci}
987db96d56Sopenharmony_ci
997db96d56Sopenharmony_cistatic PyObject *
1007db96d56Sopenharmony_cinew_module(PyTypeObject *mt, PyObject *args, PyObject *kws)
1017db96d56Sopenharmony_ci{
1027db96d56Sopenharmony_ci    PyObject *m = (PyObject *)new_module_notrack(mt);
1037db96d56Sopenharmony_ci    if (m != NULL) {
1047db96d56Sopenharmony_ci        PyObject_GC_Track(m);
1057db96d56Sopenharmony_ci    }
1067db96d56Sopenharmony_ci    return m;
1077db96d56Sopenharmony_ci}
1087db96d56Sopenharmony_ci
1097db96d56Sopenharmony_ciPyObject *
1107db96d56Sopenharmony_ciPyModule_NewObject(PyObject *name)
1117db96d56Sopenharmony_ci{
1127db96d56Sopenharmony_ci    PyModuleObject *m = new_module_notrack(&PyModule_Type);
1137db96d56Sopenharmony_ci    if (m == NULL)
1147db96d56Sopenharmony_ci        return NULL;
1157db96d56Sopenharmony_ci    if (module_init_dict(m, m->md_dict, name, NULL) != 0)
1167db96d56Sopenharmony_ci        goto fail;
1177db96d56Sopenharmony_ci    PyObject_GC_Track(m);
1187db96d56Sopenharmony_ci    return (PyObject *)m;
1197db96d56Sopenharmony_ci
1207db96d56Sopenharmony_ci fail:
1217db96d56Sopenharmony_ci    Py_DECREF(m);
1227db96d56Sopenharmony_ci    return NULL;
1237db96d56Sopenharmony_ci}
1247db96d56Sopenharmony_ci
1257db96d56Sopenharmony_ciPyObject *
1267db96d56Sopenharmony_ciPyModule_New(const char *name)
1277db96d56Sopenharmony_ci{
1287db96d56Sopenharmony_ci    PyObject *nameobj, *module;
1297db96d56Sopenharmony_ci    nameobj = PyUnicode_FromString(name);
1307db96d56Sopenharmony_ci    if (nameobj == NULL)
1317db96d56Sopenharmony_ci        return NULL;
1327db96d56Sopenharmony_ci    module = PyModule_NewObject(nameobj);
1337db96d56Sopenharmony_ci    Py_DECREF(nameobj);
1347db96d56Sopenharmony_ci    return module;
1357db96d56Sopenharmony_ci}
1367db96d56Sopenharmony_ci
1377db96d56Sopenharmony_ci/* Check API/ABI version
1387db96d56Sopenharmony_ci * Issues a warning on mismatch, which is usually not fatal.
1397db96d56Sopenharmony_ci * Returns 0 if an exception is raised.
1407db96d56Sopenharmony_ci */
1417db96d56Sopenharmony_cistatic int
1427db96d56Sopenharmony_cicheck_api_version(const char *name, int module_api_version)
1437db96d56Sopenharmony_ci{
1447db96d56Sopenharmony_ci    if (module_api_version != PYTHON_API_VERSION && module_api_version != PYTHON_ABI_VERSION) {
1457db96d56Sopenharmony_ci        int err;
1467db96d56Sopenharmony_ci        err = PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
1477db96d56Sopenharmony_ci            "Python C API version mismatch for module %.100s: "
1487db96d56Sopenharmony_ci            "This Python has API version %d, module %.100s has version %d.",
1497db96d56Sopenharmony_ci             name,
1507db96d56Sopenharmony_ci             PYTHON_API_VERSION, name, module_api_version);
1517db96d56Sopenharmony_ci        if (err)
1527db96d56Sopenharmony_ci            return 0;
1537db96d56Sopenharmony_ci    }
1547db96d56Sopenharmony_ci    return 1;
1557db96d56Sopenharmony_ci}
1567db96d56Sopenharmony_ci
1577db96d56Sopenharmony_cistatic int
1587db96d56Sopenharmony_ci_add_methods_to_object(PyObject *module, PyObject *name, PyMethodDef *functions)
1597db96d56Sopenharmony_ci{
1607db96d56Sopenharmony_ci    PyObject *func;
1617db96d56Sopenharmony_ci    PyMethodDef *fdef;
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ci    for (fdef = functions; fdef->ml_name != NULL; fdef++) {
1647db96d56Sopenharmony_ci        if ((fdef->ml_flags & METH_CLASS) ||
1657db96d56Sopenharmony_ci            (fdef->ml_flags & METH_STATIC)) {
1667db96d56Sopenharmony_ci            PyErr_SetString(PyExc_ValueError,
1677db96d56Sopenharmony_ci                            "module functions cannot set"
1687db96d56Sopenharmony_ci                            " METH_CLASS or METH_STATIC");
1697db96d56Sopenharmony_ci            return -1;
1707db96d56Sopenharmony_ci        }
1717db96d56Sopenharmony_ci        func = PyCFunction_NewEx(fdef, (PyObject*)module, name);
1727db96d56Sopenharmony_ci        if (func == NULL) {
1737db96d56Sopenharmony_ci            return -1;
1747db96d56Sopenharmony_ci        }
1757db96d56Sopenharmony_ci        if (PyObject_SetAttrString(module, fdef->ml_name, func) != 0) {
1767db96d56Sopenharmony_ci            Py_DECREF(func);
1777db96d56Sopenharmony_ci            return -1;
1787db96d56Sopenharmony_ci        }
1797db96d56Sopenharmony_ci        Py_DECREF(func);
1807db96d56Sopenharmony_ci    }
1817db96d56Sopenharmony_ci
1827db96d56Sopenharmony_ci    return 0;
1837db96d56Sopenharmony_ci}
1847db96d56Sopenharmony_ci
1857db96d56Sopenharmony_ciPyObject *
1867db96d56Sopenharmony_ciPyModule_Create2(PyModuleDef* module, int module_api_version)
1877db96d56Sopenharmony_ci{
1887db96d56Sopenharmony_ci    if (!_PyImport_IsInitialized(_PyInterpreterState_GET())) {
1897db96d56Sopenharmony_ci        PyErr_SetString(PyExc_SystemError,
1907db96d56Sopenharmony_ci                        "Python import machinery not initialized");
1917db96d56Sopenharmony_ci        return NULL;
1927db96d56Sopenharmony_ci    }
1937db96d56Sopenharmony_ci    return _PyModule_CreateInitialized(module, module_api_version);
1947db96d56Sopenharmony_ci}
1957db96d56Sopenharmony_ci
1967db96d56Sopenharmony_ciPyObject *
1977db96d56Sopenharmony_ci_PyModule_CreateInitialized(PyModuleDef* module, int module_api_version)
1987db96d56Sopenharmony_ci{
1997db96d56Sopenharmony_ci    const char* name;
2007db96d56Sopenharmony_ci    PyModuleObject *m;
2017db96d56Sopenharmony_ci
2027db96d56Sopenharmony_ci    if (!PyModuleDef_Init(module))
2037db96d56Sopenharmony_ci        return NULL;
2047db96d56Sopenharmony_ci    name = module->m_name;
2057db96d56Sopenharmony_ci    if (!check_api_version(name, module_api_version)) {
2067db96d56Sopenharmony_ci        return NULL;
2077db96d56Sopenharmony_ci    }
2087db96d56Sopenharmony_ci    if (module->m_slots) {
2097db96d56Sopenharmony_ci        PyErr_Format(
2107db96d56Sopenharmony_ci            PyExc_SystemError,
2117db96d56Sopenharmony_ci            "module %s: PyModule_Create is incompatible with m_slots", name);
2127db96d56Sopenharmony_ci        return NULL;
2137db96d56Sopenharmony_ci    }
2147db96d56Sopenharmony_ci    /* Make sure name is fully qualified.
2157db96d56Sopenharmony_ci
2167db96d56Sopenharmony_ci       This is a bit of a hack: when the shared library is loaded,
2177db96d56Sopenharmony_ci       the module name is "package.module", but the module calls
2187db96d56Sopenharmony_ci       PyModule_Create*() with just "module" for the name.  The shared
2197db96d56Sopenharmony_ci       library loader squirrels away the true name of the module in
2207db96d56Sopenharmony_ci       _Py_PackageContext, and PyModule_Create*() will substitute this
2217db96d56Sopenharmony_ci       (if the name actually matches).
2227db96d56Sopenharmony_ci    */
2237db96d56Sopenharmony_ci    if (_Py_PackageContext != NULL) {
2247db96d56Sopenharmony_ci        const char *p = strrchr(_Py_PackageContext, '.');
2257db96d56Sopenharmony_ci        if (p != NULL && strcmp(module->m_name, p+1) == 0) {
2267db96d56Sopenharmony_ci            name = _Py_PackageContext;
2277db96d56Sopenharmony_ci            _Py_PackageContext = NULL;
2287db96d56Sopenharmony_ci        }
2297db96d56Sopenharmony_ci    }
2307db96d56Sopenharmony_ci    if ((m = (PyModuleObject*)PyModule_New(name)) == NULL)
2317db96d56Sopenharmony_ci        return NULL;
2327db96d56Sopenharmony_ci
2337db96d56Sopenharmony_ci    if (module->m_size > 0) {
2347db96d56Sopenharmony_ci        m->md_state = PyMem_Malloc(module->m_size);
2357db96d56Sopenharmony_ci        if (!m->md_state) {
2367db96d56Sopenharmony_ci            PyErr_NoMemory();
2377db96d56Sopenharmony_ci            Py_DECREF(m);
2387db96d56Sopenharmony_ci            return NULL;
2397db96d56Sopenharmony_ci        }
2407db96d56Sopenharmony_ci        memset(m->md_state, 0, module->m_size);
2417db96d56Sopenharmony_ci    }
2427db96d56Sopenharmony_ci
2437db96d56Sopenharmony_ci    if (module->m_methods != NULL) {
2447db96d56Sopenharmony_ci        if (PyModule_AddFunctions((PyObject *) m, module->m_methods) != 0) {
2457db96d56Sopenharmony_ci            Py_DECREF(m);
2467db96d56Sopenharmony_ci            return NULL;
2477db96d56Sopenharmony_ci        }
2487db96d56Sopenharmony_ci    }
2497db96d56Sopenharmony_ci    if (module->m_doc != NULL) {
2507db96d56Sopenharmony_ci        if (PyModule_SetDocString((PyObject *) m, module->m_doc) != 0) {
2517db96d56Sopenharmony_ci            Py_DECREF(m);
2527db96d56Sopenharmony_ci            return NULL;
2537db96d56Sopenharmony_ci        }
2547db96d56Sopenharmony_ci    }
2557db96d56Sopenharmony_ci    m->md_def = module;
2567db96d56Sopenharmony_ci    return (PyObject*)m;
2577db96d56Sopenharmony_ci}
2587db96d56Sopenharmony_ci
2597db96d56Sopenharmony_ciPyObject *
2607db96d56Sopenharmony_ciPyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_version)
2617db96d56Sopenharmony_ci{
2627db96d56Sopenharmony_ci    PyModuleDef_Slot* cur_slot;
2637db96d56Sopenharmony_ci    PyObject *(*create)(PyObject *, PyModuleDef*) = NULL;
2647db96d56Sopenharmony_ci    PyObject *nameobj;
2657db96d56Sopenharmony_ci    PyObject *m = NULL;
2667db96d56Sopenharmony_ci    int has_execution_slots = 0;
2677db96d56Sopenharmony_ci    const char *name;
2687db96d56Sopenharmony_ci    int ret;
2697db96d56Sopenharmony_ci
2707db96d56Sopenharmony_ci    PyModuleDef_Init(def);
2717db96d56Sopenharmony_ci
2727db96d56Sopenharmony_ci    nameobj = PyObject_GetAttrString(spec, "name");
2737db96d56Sopenharmony_ci    if (nameobj == NULL) {
2747db96d56Sopenharmony_ci        return NULL;
2757db96d56Sopenharmony_ci    }
2767db96d56Sopenharmony_ci    name = PyUnicode_AsUTF8(nameobj);
2777db96d56Sopenharmony_ci    if (name == NULL) {
2787db96d56Sopenharmony_ci        goto error;
2797db96d56Sopenharmony_ci    }
2807db96d56Sopenharmony_ci
2817db96d56Sopenharmony_ci    if (!check_api_version(name, module_api_version)) {
2827db96d56Sopenharmony_ci        goto error;
2837db96d56Sopenharmony_ci    }
2847db96d56Sopenharmony_ci
2857db96d56Sopenharmony_ci    if (def->m_size < 0) {
2867db96d56Sopenharmony_ci        PyErr_Format(
2877db96d56Sopenharmony_ci            PyExc_SystemError,
2887db96d56Sopenharmony_ci            "module %s: m_size may not be negative for multi-phase initialization",
2897db96d56Sopenharmony_ci            name);
2907db96d56Sopenharmony_ci        goto error;
2917db96d56Sopenharmony_ci    }
2927db96d56Sopenharmony_ci
2937db96d56Sopenharmony_ci    for (cur_slot = def->m_slots; cur_slot && cur_slot->slot; cur_slot++) {
2947db96d56Sopenharmony_ci        if (cur_slot->slot == Py_mod_create) {
2957db96d56Sopenharmony_ci            if (create) {
2967db96d56Sopenharmony_ci                PyErr_Format(
2977db96d56Sopenharmony_ci                    PyExc_SystemError,
2987db96d56Sopenharmony_ci                    "module %s has multiple create slots",
2997db96d56Sopenharmony_ci                    name);
3007db96d56Sopenharmony_ci                goto error;
3017db96d56Sopenharmony_ci            }
3027db96d56Sopenharmony_ci            create = cur_slot->value;
3037db96d56Sopenharmony_ci        } else if (cur_slot->slot < 0 || cur_slot->slot > _Py_mod_LAST_SLOT) {
3047db96d56Sopenharmony_ci            PyErr_Format(
3057db96d56Sopenharmony_ci                PyExc_SystemError,
3067db96d56Sopenharmony_ci                "module %s uses unknown slot ID %i",
3077db96d56Sopenharmony_ci                name, cur_slot->slot);
3087db96d56Sopenharmony_ci            goto error;
3097db96d56Sopenharmony_ci        } else {
3107db96d56Sopenharmony_ci            has_execution_slots = 1;
3117db96d56Sopenharmony_ci        }
3127db96d56Sopenharmony_ci    }
3137db96d56Sopenharmony_ci
3147db96d56Sopenharmony_ci    if (create) {
3157db96d56Sopenharmony_ci        m = create(spec, def);
3167db96d56Sopenharmony_ci        if (m == NULL) {
3177db96d56Sopenharmony_ci            if (!PyErr_Occurred()) {
3187db96d56Sopenharmony_ci                PyErr_Format(
3197db96d56Sopenharmony_ci                    PyExc_SystemError,
3207db96d56Sopenharmony_ci                    "creation of module %s failed without setting an exception",
3217db96d56Sopenharmony_ci                    name);
3227db96d56Sopenharmony_ci            }
3237db96d56Sopenharmony_ci            goto error;
3247db96d56Sopenharmony_ci        } else {
3257db96d56Sopenharmony_ci            if (PyErr_Occurred()) {
3267db96d56Sopenharmony_ci                PyErr_Format(PyExc_SystemError,
3277db96d56Sopenharmony_ci                            "creation of module %s raised unreported exception",
3287db96d56Sopenharmony_ci                            name);
3297db96d56Sopenharmony_ci                goto error;
3307db96d56Sopenharmony_ci            }
3317db96d56Sopenharmony_ci        }
3327db96d56Sopenharmony_ci    } else {
3337db96d56Sopenharmony_ci        m = PyModule_NewObject(nameobj);
3347db96d56Sopenharmony_ci        if (m == NULL) {
3357db96d56Sopenharmony_ci            goto error;
3367db96d56Sopenharmony_ci        }
3377db96d56Sopenharmony_ci    }
3387db96d56Sopenharmony_ci
3397db96d56Sopenharmony_ci    if (PyModule_Check(m)) {
3407db96d56Sopenharmony_ci        ((PyModuleObject*)m)->md_state = NULL;
3417db96d56Sopenharmony_ci        ((PyModuleObject*)m)->md_def = def;
3427db96d56Sopenharmony_ci    } else {
3437db96d56Sopenharmony_ci        if (def->m_size > 0 || def->m_traverse || def->m_clear || def->m_free) {
3447db96d56Sopenharmony_ci            PyErr_Format(
3457db96d56Sopenharmony_ci                PyExc_SystemError,
3467db96d56Sopenharmony_ci                "module %s is not a module object, but requests module state",
3477db96d56Sopenharmony_ci                name);
3487db96d56Sopenharmony_ci            goto error;
3497db96d56Sopenharmony_ci        }
3507db96d56Sopenharmony_ci        if (has_execution_slots) {
3517db96d56Sopenharmony_ci            PyErr_Format(
3527db96d56Sopenharmony_ci                PyExc_SystemError,
3537db96d56Sopenharmony_ci                "module %s specifies execution slots, but did not create "
3547db96d56Sopenharmony_ci                    "a ModuleType instance",
3557db96d56Sopenharmony_ci                name);
3567db96d56Sopenharmony_ci            goto error;
3577db96d56Sopenharmony_ci        }
3587db96d56Sopenharmony_ci    }
3597db96d56Sopenharmony_ci
3607db96d56Sopenharmony_ci    if (def->m_methods != NULL) {
3617db96d56Sopenharmony_ci        ret = _add_methods_to_object(m, nameobj, def->m_methods);
3627db96d56Sopenharmony_ci        if (ret != 0) {
3637db96d56Sopenharmony_ci            goto error;
3647db96d56Sopenharmony_ci        }
3657db96d56Sopenharmony_ci    }
3667db96d56Sopenharmony_ci
3677db96d56Sopenharmony_ci    if (def->m_doc != NULL) {
3687db96d56Sopenharmony_ci        ret = PyModule_SetDocString(m, def->m_doc);
3697db96d56Sopenharmony_ci        if (ret != 0) {
3707db96d56Sopenharmony_ci            goto error;
3717db96d56Sopenharmony_ci        }
3727db96d56Sopenharmony_ci    }
3737db96d56Sopenharmony_ci
3747db96d56Sopenharmony_ci    Py_DECREF(nameobj);
3757db96d56Sopenharmony_ci    return m;
3767db96d56Sopenharmony_ci
3777db96d56Sopenharmony_cierror:
3787db96d56Sopenharmony_ci    Py_DECREF(nameobj);
3797db96d56Sopenharmony_ci    Py_XDECREF(m);
3807db96d56Sopenharmony_ci    return NULL;
3817db96d56Sopenharmony_ci}
3827db96d56Sopenharmony_ci
3837db96d56Sopenharmony_ciint
3847db96d56Sopenharmony_ciPyModule_ExecDef(PyObject *module, PyModuleDef *def)
3857db96d56Sopenharmony_ci{
3867db96d56Sopenharmony_ci    PyModuleDef_Slot *cur_slot;
3877db96d56Sopenharmony_ci    const char *name;
3887db96d56Sopenharmony_ci    int ret;
3897db96d56Sopenharmony_ci
3907db96d56Sopenharmony_ci    name = PyModule_GetName(module);
3917db96d56Sopenharmony_ci    if (name == NULL) {
3927db96d56Sopenharmony_ci        return -1;
3937db96d56Sopenharmony_ci    }
3947db96d56Sopenharmony_ci
3957db96d56Sopenharmony_ci    if (def->m_size >= 0) {
3967db96d56Sopenharmony_ci        PyModuleObject *md = (PyModuleObject*)module;
3977db96d56Sopenharmony_ci        if (md->md_state == NULL) {
3987db96d56Sopenharmony_ci            /* Always set a state pointer; this serves as a marker to skip
3997db96d56Sopenharmony_ci             * multiple initialization (importlib.reload() is no-op) */
4007db96d56Sopenharmony_ci            md->md_state = PyMem_Malloc(def->m_size);
4017db96d56Sopenharmony_ci            if (!md->md_state) {
4027db96d56Sopenharmony_ci                PyErr_NoMemory();
4037db96d56Sopenharmony_ci                return -1;
4047db96d56Sopenharmony_ci            }
4057db96d56Sopenharmony_ci            memset(md->md_state, 0, def->m_size);
4067db96d56Sopenharmony_ci        }
4077db96d56Sopenharmony_ci    }
4087db96d56Sopenharmony_ci
4097db96d56Sopenharmony_ci    if (def->m_slots == NULL) {
4107db96d56Sopenharmony_ci        return 0;
4117db96d56Sopenharmony_ci    }
4127db96d56Sopenharmony_ci
4137db96d56Sopenharmony_ci    for (cur_slot = def->m_slots; cur_slot && cur_slot->slot; cur_slot++) {
4147db96d56Sopenharmony_ci        switch (cur_slot->slot) {
4157db96d56Sopenharmony_ci            case Py_mod_create:
4167db96d56Sopenharmony_ci                /* handled in PyModule_FromDefAndSpec2 */
4177db96d56Sopenharmony_ci                break;
4187db96d56Sopenharmony_ci            case Py_mod_exec:
4197db96d56Sopenharmony_ci                ret = ((int (*)(PyObject *))cur_slot->value)(module);
4207db96d56Sopenharmony_ci                if (ret != 0) {
4217db96d56Sopenharmony_ci                    if (!PyErr_Occurred()) {
4227db96d56Sopenharmony_ci                        PyErr_Format(
4237db96d56Sopenharmony_ci                            PyExc_SystemError,
4247db96d56Sopenharmony_ci                            "execution of module %s failed without setting an exception",
4257db96d56Sopenharmony_ci                            name);
4267db96d56Sopenharmony_ci                    }
4277db96d56Sopenharmony_ci                    return -1;
4287db96d56Sopenharmony_ci                }
4297db96d56Sopenharmony_ci                if (PyErr_Occurred()) {
4307db96d56Sopenharmony_ci                    PyErr_Format(
4317db96d56Sopenharmony_ci                        PyExc_SystemError,
4327db96d56Sopenharmony_ci                        "execution of module %s raised unreported exception",
4337db96d56Sopenharmony_ci                        name);
4347db96d56Sopenharmony_ci                    return -1;
4357db96d56Sopenharmony_ci                }
4367db96d56Sopenharmony_ci                break;
4377db96d56Sopenharmony_ci            default:
4387db96d56Sopenharmony_ci                PyErr_Format(
4397db96d56Sopenharmony_ci                    PyExc_SystemError,
4407db96d56Sopenharmony_ci                    "module %s initialized with unknown slot %i",
4417db96d56Sopenharmony_ci                    name, cur_slot->slot);
4427db96d56Sopenharmony_ci                return -1;
4437db96d56Sopenharmony_ci        }
4447db96d56Sopenharmony_ci    }
4457db96d56Sopenharmony_ci    return 0;
4467db96d56Sopenharmony_ci}
4477db96d56Sopenharmony_ci
4487db96d56Sopenharmony_ciint
4497db96d56Sopenharmony_ciPyModule_AddFunctions(PyObject *m, PyMethodDef *functions)
4507db96d56Sopenharmony_ci{
4517db96d56Sopenharmony_ci    int res;
4527db96d56Sopenharmony_ci    PyObject *name = PyModule_GetNameObject(m);
4537db96d56Sopenharmony_ci    if (name == NULL) {
4547db96d56Sopenharmony_ci        return -1;
4557db96d56Sopenharmony_ci    }
4567db96d56Sopenharmony_ci
4577db96d56Sopenharmony_ci    res = _add_methods_to_object(m, name, functions);
4587db96d56Sopenharmony_ci    Py_DECREF(name);
4597db96d56Sopenharmony_ci    return res;
4607db96d56Sopenharmony_ci}
4617db96d56Sopenharmony_ci
4627db96d56Sopenharmony_ciint
4637db96d56Sopenharmony_ciPyModule_SetDocString(PyObject *m, const char *doc)
4647db96d56Sopenharmony_ci{
4657db96d56Sopenharmony_ci    PyObject *v;
4667db96d56Sopenharmony_ci
4677db96d56Sopenharmony_ci    v = PyUnicode_FromString(doc);
4687db96d56Sopenharmony_ci    if (v == NULL || PyObject_SetAttr(m, &_Py_ID(__doc__), v) != 0) {
4697db96d56Sopenharmony_ci        Py_XDECREF(v);
4707db96d56Sopenharmony_ci        return -1;
4717db96d56Sopenharmony_ci    }
4727db96d56Sopenharmony_ci    Py_DECREF(v);
4737db96d56Sopenharmony_ci    return 0;
4747db96d56Sopenharmony_ci}
4757db96d56Sopenharmony_ci
4767db96d56Sopenharmony_ciPyObject *
4777db96d56Sopenharmony_ciPyModule_GetDict(PyObject *m)
4787db96d56Sopenharmony_ci{
4797db96d56Sopenharmony_ci    if (!PyModule_Check(m)) {
4807db96d56Sopenharmony_ci        PyErr_BadInternalCall();
4817db96d56Sopenharmony_ci        return NULL;
4827db96d56Sopenharmony_ci    }
4837db96d56Sopenharmony_ci    return _PyModule_GetDict(m);
4847db96d56Sopenharmony_ci}
4857db96d56Sopenharmony_ci
4867db96d56Sopenharmony_ciPyObject*
4877db96d56Sopenharmony_ciPyModule_GetNameObject(PyObject *m)
4887db96d56Sopenharmony_ci{
4897db96d56Sopenharmony_ci    PyObject *d;
4907db96d56Sopenharmony_ci    PyObject *name;
4917db96d56Sopenharmony_ci    if (!PyModule_Check(m)) {
4927db96d56Sopenharmony_ci        PyErr_BadArgument();
4937db96d56Sopenharmony_ci        return NULL;
4947db96d56Sopenharmony_ci    }
4957db96d56Sopenharmony_ci    d = ((PyModuleObject *)m)->md_dict;
4967db96d56Sopenharmony_ci    if (d == NULL || !PyDict_Check(d) ||
4977db96d56Sopenharmony_ci        (name = PyDict_GetItemWithError(d, &_Py_ID(__name__))) == NULL ||
4987db96d56Sopenharmony_ci        !PyUnicode_Check(name))
4997db96d56Sopenharmony_ci    {
5007db96d56Sopenharmony_ci        if (!PyErr_Occurred()) {
5017db96d56Sopenharmony_ci            PyErr_SetString(PyExc_SystemError, "nameless module");
5027db96d56Sopenharmony_ci        }
5037db96d56Sopenharmony_ci        return NULL;
5047db96d56Sopenharmony_ci    }
5057db96d56Sopenharmony_ci    Py_INCREF(name);
5067db96d56Sopenharmony_ci    return name;
5077db96d56Sopenharmony_ci}
5087db96d56Sopenharmony_ci
5097db96d56Sopenharmony_ciconst char *
5107db96d56Sopenharmony_ciPyModule_GetName(PyObject *m)
5117db96d56Sopenharmony_ci{
5127db96d56Sopenharmony_ci    PyObject *name = PyModule_GetNameObject(m);
5137db96d56Sopenharmony_ci    if (name == NULL) {
5147db96d56Sopenharmony_ci        return NULL;
5157db96d56Sopenharmony_ci    }
5167db96d56Sopenharmony_ci    assert(Py_REFCNT(name) >= 2);
5177db96d56Sopenharmony_ci    Py_DECREF(name);   /* module dict has still a reference */
5187db96d56Sopenharmony_ci    return PyUnicode_AsUTF8(name);
5197db96d56Sopenharmony_ci}
5207db96d56Sopenharmony_ci
5217db96d56Sopenharmony_ciPyObject*
5227db96d56Sopenharmony_ciPyModule_GetFilenameObject(PyObject *m)
5237db96d56Sopenharmony_ci{
5247db96d56Sopenharmony_ci    PyObject *d;
5257db96d56Sopenharmony_ci    PyObject *fileobj;
5267db96d56Sopenharmony_ci    if (!PyModule_Check(m)) {
5277db96d56Sopenharmony_ci        PyErr_BadArgument();
5287db96d56Sopenharmony_ci        return NULL;
5297db96d56Sopenharmony_ci    }
5307db96d56Sopenharmony_ci    d = ((PyModuleObject *)m)->md_dict;
5317db96d56Sopenharmony_ci    if (d == NULL ||
5327db96d56Sopenharmony_ci        (fileobj = PyDict_GetItemWithError(d, &_Py_ID(__file__))) == NULL ||
5337db96d56Sopenharmony_ci        !PyUnicode_Check(fileobj))
5347db96d56Sopenharmony_ci    {
5357db96d56Sopenharmony_ci        if (!PyErr_Occurred()) {
5367db96d56Sopenharmony_ci            PyErr_SetString(PyExc_SystemError, "module filename missing");
5377db96d56Sopenharmony_ci        }
5387db96d56Sopenharmony_ci        return NULL;
5397db96d56Sopenharmony_ci    }
5407db96d56Sopenharmony_ci    Py_INCREF(fileobj);
5417db96d56Sopenharmony_ci    return fileobj;
5427db96d56Sopenharmony_ci}
5437db96d56Sopenharmony_ci
5447db96d56Sopenharmony_ciconst char *
5457db96d56Sopenharmony_ciPyModule_GetFilename(PyObject *m)
5467db96d56Sopenharmony_ci{
5477db96d56Sopenharmony_ci    PyObject *fileobj;
5487db96d56Sopenharmony_ci    const char *utf8;
5497db96d56Sopenharmony_ci    fileobj = PyModule_GetFilenameObject(m);
5507db96d56Sopenharmony_ci    if (fileobj == NULL)
5517db96d56Sopenharmony_ci        return NULL;
5527db96d56Sopenharmony_ci    utf8 = PyUnicode_AsUTF8(fileobj);
5537db96d56Sopenharmony_ci    Py_DECREF(fileobj);   /* module dict has still a reference */
5547db96d56Sopenharmony_ci    return utf8;
5557db96d56Sopenharmony_ci}
5567db96d56Sopenharmony_ci
5577db96d56Sopenharmony_ciPyModuleDef*
5587db96d56Sopenharmony_ciPyModule_GetDef(PyObject* m)
5597db96d56Sopenharmony_ci{
5607db96d56Sopenharmony_ci    if (!PyModule_Check(m)) {
5617db96d56Sopenharmony_ci        PyErr_BadArgument();
5627db96d56Sopenharmony_ci        return NULL;
5637db96d56Sopenharmony_ci    }
5647db96d56Sopenharmony_ci    return _PyModule_GetDef(m);
5657db96d56Sopenharmony_ci}
5667db96d56Sopenharmony_ci
5677db96d56Sopenharmony_civoid*
5687db96d56Sopenharmony_ciPyModule_GetState(PyObject* m)
5697db96d56Sopenharmony_ci{
5707db96d56Sopenharmony_ci    if (!PyModule_Check(m)) {
5717db96d56Sopenharmony_ci        PyErr_BadArgument();
5727db96d56Sopenharmony_ci        return NULL;
5737db96d56Sopenharmony_ci    }
5747db96d56Sopenharmony_ci    return _PyModule_GetState(m);
5757db96d56Sopenharmony_ci}
5767db96d56Sopenharmony_ci
5777db96d56Sopenharmony_civoid
5787db96d56Sopenharmony_ci_PyModule_Clear(PyObject *m)
5797db96d56Sopenharmony_ci{
5807db96d56Sopenharmony_ci    PyObject *d = ((PyModuleObject *)m)->md_dict;
5817db96d56Sopenharmony_ci    if (d != NULL)
5827db96d56Sopenharmony_ci        _PyModule_ClearDict(d);
5837db96d56Sopenharmony_ci}
5847db96d56Sopenharmony_ci
5857db96d56Sopenharmony_civoid
5867db96d56Sopenharmony_ci_PyModule_ClearDict(PyObject *d)
5877db96d56Sopenharmony_ci{
5887db96d56Sopenharmony_ci    /* To make the execution order of destructors for global
5897db96d56Sopenharmony_ci       objects a bit more predictable, we first zap all objects
5907db96d56Sopenharmony_ci       whose name starts with a single underscore, before we clear
5917db96d56Sopenharmony_ci       the entire dictionary.  We zap them by replacing them with
5927db96d56Sopenharmony_ci       None, rather than deleting them from the dictionary, to
5937db96d56Sopenharmony_ci       avoid rehashing the dictionary (to some extent). */
5947db96d56Sopenharmony_ci
5957db96d56Sopenharmony_ci    Py_ssize_t pos;
5967db96d56Sopenharmony_ci    PyObject *key, *value;
5977db96d56Sopenharmony_ci
5987db96d56Sopenharmony_ci    int verbose = _Py_GetConfig()->verbose;
5997db96d56Sopenharmony_ci
6007db96d56Sopenharmony_ci    /* First, clear only names starting with a single underscore */
6017db96d56Sopenharmony_ci    pos = 0;
6027db96d56Sopenharmony_ci    while (PyDict_Next(d, &pos, &key, &value)) {
6037db96d56Sopenharmony_ci        if (value != Py_None && PyUnicode_Check(key)) {
6047db96d56Sopenharmony_ci            if (PyUnicode_READ_CHAR(key, 0) == '_' &&
6057db96d56Sopenharmony_ci                PyUnicode_READ_CHAR(key, 1) != '_') {
6067db96d56Sopenharmony_ci                if (verbose > 1) {
6077db96d56Sopenharmony_ci                    const char *s = PyUnicode_AsUTF8(key);
6087db96d56Sopenharmony_ci                    if (s != NULL)
6097db96d56Sopenharmony_ci                        PySys_WriteStderr("#   clear[1] %s\n", s);
6107db96d56Sopenharmony_ci                    else
6117db96d56Sopenharmony_ci                        PyErr_Clear();
6127db96d56Sopenharmony_ci                }
6137db96d56Sopenharmony_ci                if (PyDict_SetItem(d, key, Py_None) != 0) {
6147db96d56Sopenharmony_ci                    PyErr_WriteUnraisable(NULL);
6157db96d56Sopenharmony_ci                }
6167db96d56Sopenharmony_ci            }
6177db96d56Sopenharmony_ci        }
6187db96d56Sopenharmony_ci    }
6197db96d56Sopenharmony_ci
6207db96d56Sopenharmony_ci    /* Next, clear all names except for __builtins__ */
6217db96d56Sopenharmony_ci    pos = 0;
6227db96d56Sopenharmony_ci    while (PyDict_Next(d, &pos, &key, &value)) {
6237db96d56Sopenharmony_ci        if (value != Py_None && PyUnicode_Check(key)) {
6247db96d56Sopenharmony_ci            if (PyUnicode_READ_CHAR(key, 0) != '_' ||
6257db96d56Sopenharmony_ci                !_PyUnicode_EqualToASCIIString(key, "__builtins__"))
6267db96d56Sopenharmony_ci            {
6277db96d56Sopenharmony_ci                if (verbose > 1) {
6287db96d56Sopenharmony_ci                    const char *s = PyUnicode_AsUTF8(key);
6297db96d56Sopenharmony_ci                    if (s != NULL)
6307db96d56Sopenharmony_ci                        PySys_WriteStderr("#   clear[2] %s\n", s);
6317db96d56Sopenharmony_ci                    else
6327db96d56Sopenharmony_ci                        PyErr_Clear();
6337db96d56Sopenharmony_ci                }
6347db96d56Sopenharmony_ci                if (PyDict_SetItem(d, key, Py_None) != 0) {
6357db96d56Sopenharmony_ci                    PyErr_WriteUnraisable(NULL);
6367db96d56Sopenharmony_ci                }
6377db96d56Sopenharmony_ci            }
6387db96d56Sopenharmony_ci        }
6397db96d56Sopenharmony_ci    }
6407db96d56Sopenharmony_ci
6417db96d56Sopenharmony_ci    /* Note: we leave __builtins__ in place, so that destructors
6427db96d56Sopenharmony_ci       of non-global objects defined in this module can still use
6437db96d56Sopenharmony_ci       builtins, in particularly 'None'. */
6447db96d56Sopenharmony_ci
6457db96d56Sopenharmony_ci}
6467db96d56Sopenharmony_ci
6477db96d56Sopenharmony_ci/*[clinic input]
6487db96d56Sopenharmony_ciclass module "PyModuleObject *" "&PyModule_Type"
6497db96d56Sopenharmony_ci[clinic start generated code]*/
6507db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3e35d4f708ecb6af]*/
6517db96d56Sopenharmony_ci
6527db96d56Sopenharmony_ci#include "clinic/moduleobject.c.h"
6537db96d56Sopenharmony_ci
6547db96d56Sopenharmony_ci/* Methods */
6557db96d56Sopenharmony_ci
6567db96d56Sopenharmony_ci/*[clinic input]
6577db96d56Sopenharmony_cimodule.__init__
6587db96d56Sopenharmony_ci    name: unicode
6597db96d56Sopenharmony_ci    doc: object = None
6607db96d56Sopenharmony_ci
6617db96d56Sopenharmony_ciCreate a module object.
6627db96d56Sopenharmony_ci
6637db96d56Sopenharmony_ciThe name must be a string; the optional doc argument can have any type.
6647db96d56Sopenharmony_ci[clinic start generated code]*/
6657db96d56Sopenharmony_ci
6667db96d56Sopenharmony_cistatic int
6677db96d56Sopenharmony_cimodule___init___impl(PyModuleObject *self, PyObject *name, PyObject *doc)
6687db96d56Sopenharmony_ci/*[clinic end generated code: output=e7e721c26ce7aad7 input=57f9e177401e5e1e]*/
6697db96d56Sopenharmony_ci{
6707db96d56Sopenharmony_ci    PyObject *dict = self->md_dict;
6717db96d56Sopenharmony_ci    if (dict == NULL) {
6727db96d56Sopenharmony_ci        dict = PyDict_New();
6737db96d56Sopenharmony_ci        if (dict == NULL)
6747db96d56Sopenharmony_ci            return -1;
6757db96d56Sopenharmony_ci        self->md_dict = dict;
6767db96d56Sopenharmony_ci    }
6777db96d56Sopenharmony_ci    if (module_init_dict(self, dict, name, doc) < 0)
6787db96d56Sopenharmony_ci        return -1;
6797db96d56Sopenharmony_ci    return 0;
6807db96d56Sopenharmony_ci}
6817db96d56Sopenharmony_ci
6827db96d56Sopenharmony_cistatic void
6837db96d56Sopenharmony_cimodule_dealloc(PyModuleObject *m)
6847db96d56Sopenharmony_ci{
6857db96d56Sopenharmony_ci    int verbose = _Py_GetConfig()->verbose;
6867db96d56Sopenharmony_ci
6877db96d56Sopenharmony_ci    PyObject_GC_UnTrack(m);
6887db96d56Sopenharmony_ci    if (verbose && m->md_name) {
6897db96d56Sopenharmony_ci        PySys_FormatStderr("# destroy %U\n", m->md_name);
6907db96d56Sopenharmony_ci    }
6917db96d56Sopenharmony_ci    if (m->md_weaklist != NULL)
6927db96d56Sopenharmony_ci        PyObject_ClearWeakRefs((PyObject *) m);
6937db96d56Sopenharmony_ci    /* bpo-39824: Don't call m_free() if m_size > 0 and md_state=NULL */
6947db96d56Sopenharmony_ci    if (m->md_def && m->md_def->m_free
6957db96d56Sopenharmony_ci        && (m->md_def->m_size <= 0 || m->md_state != NULL))
6967db96d56Sopenharmony_ci    {
6977db96d56Sopenharmony_ci        m->md_def->m_free(m);
6987db96d56Sopenharmony_ci    }
6997db96d56Sopenharmony_ci    Py_XDECREF(m->md_dict);
7007db96d56Sopenharmony_ci    Py_XDECREF(m->md_name);
7017db96d56Sopenharmony_ci    if (m->md_state != NULL)
7027db96d56Sopenharmony_ci        PyMem_Free(m->md_state);
7037db96d56Sopenharmony_ci    Py_TYPE(m)->tp_free((PyObject *)m);
7047db96d56Sopenharmony_ci}
7057db96d56Sopenharmony_ci
7067db96d56Sopenharmony_cistatic PyObject *
7077db96d56Sopenharmony_cimodule_repr(PyModuleObject *m)
7087db96d56Sopenharmony_ci{
7097db96d56Sopenharmony_ci    PyInterpreterState *interp = _PyInterpreterState_GET();
7107db96d56Sopenharmony_ci
7117db96d56Sopenharmony_ci    return PyObject_CallMethod(interp->importlib, "_module_repr", "O", m);
7127db96d56Sopenharmony_ci}
7137db96d56Sopenharmony_ci
7147db96d56Sopenharmony_ci/* Check if the "_initializing" attribute of the module spec is set to true.
7157db96d56Sopenharmony_ci   Clear the exception and return 0 if spec is NULL.
7167db96d56Sopenharmony_ci */
7177db96d56Sopenharmony_ciint
7187db96d56Sopenharmony_ci_PyModuleSpec_IsInitializing(PyObject *spec)
7197db96d56Sopenharmony_ci{
7207db96d56Sopenharmony_ci    if (spec != NULL) {
7217db96d56Sopenharmony_ci        PyObject *value = PyObject_GetAttr(spec, &_Py_ID(_initializing));
7227db96d56Sopenharmony_ci        if (value != NULL) {
7237db96d56Sopenharmony_ci            int initializing = PyObject_IsTrue(value);
7247db96d56Sopenharmony_ci            Py_DECREF(value);
7257db96d56Sopenharmony_ci            if (initializing >= 0) {
7267db96d56Sopenharmony_ci                return initializing;
7277db96d56Sopenharmony_ci            }
7287db96d56Sopenharmony_ci        }
7297db96d56Sopenharmony_ci    }
7307db96d56Sopenharmony_ci    PyErr_Clear();
7317db96d56Sopenharmony_ci    return 0;
7327db96d56Sopenharmony_ci}
7337db96d56Sopenharmony_ci
7347db96d56Sopenharmony_ci/* Check if the submodule name is in the "_uninitialized_submodules" attribute
7357db96d56Sopenharmony_ci   of the module spec.
7367db96d56Sopenharmony_ci */
7377db96d56Sopenharmony_ciint
7387db96d56Sopenharmony_ci_PyModuleSpec_IsUninitializedSubmodule(PyObject *spec, PyObject *name)
7397db96d56Sopenharmony_ci{
7407db96d56Sopenharmony_ci    if (spec == NULL) {
7417db96d56Sopenharmony_ci         return 0;
7427db96d56Sopenharmony_ci    }
7437db96d56Sopenharmony_ci
7447db96d56Sopenharmony_ci    PyObject *value = PyObject_GetAttr(spec, &_Py_ID(_uninitialized_submodules));
7457db96d56Sopenharmony_ci    if (value == NULL) {
7467db96d56Sopenharmony_ci        return 0;
7477db96d56Sopenharmony_ci    }
7487db96d56Sopenharmony_ci
7497db96d56Sopenharmony_ci    int is_uninitialized = PySequence_Contains(value, name);
7507db96d56Sopenharmony_ci    Py_DECREF(value);
7517db96d56Sopenharmony_ci    if (is_uninitialized == -1) {
7527db96d56Sopenharmony_ci        return 0;
7537db96d56Sopenharmony_ci    }
7547db96d56Sopenharmony_ci    return is_uninitialized;
7557db96d56Sopenharmony_ci}
7567db96d56Sopenharmony_ci
7577db96d56Sopenharmony_cistatic PyObject*
7587db96d56Sopenharmony_cimodule_getattro(PyModuleObject *m, PyObject *name)
7597db96d56Sopenharmony_ci{
7607db96d56Sopenharmony_ci    PyObject *attr, *mod_name, *getattr;
7617db96d56Sopenharmony_ci    attr = PyObject_GenericGetAttr((PyObject *)m, name);
7627db96d56Sopenharmony_ci    if (attr || !PyErr_ExceptionMatches(PyExc_AttributeError)) {
7637db96d56Sopenharmony_ci        return attr;
7647db96d56Sopenharmony_ci    }
7657db96d56Sopenharmony_ci    PyErr_Clear();
7667db96d56Sopenharmony_ci    assert(m->md_dict != NULL);
7677db96d56Sopenharmony_ci    getattr = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__getattr__));
7687db96d56Sopenharmony_ci    if (getattr) {
7697db96d56Sopenharmony_ci        return PyObject_CallOneArg(getattr, name);
7707db96d56Sopenharmony_ci    }
7717db96d56Sopenharmony_ci    if (PyErr_Occurred()) {
7727db96d56Sopenharmony_ci        return NULL;
7737db96d56Sopenharmony_ci    }
7747db96d56Sopenharmony_ci    mod_name = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__name__));
7757db96d56Sopenharmony_ci    if (mod_name && PyUnicode_Check(mod_name)) {
7767db96d56Sopenharmony_ci        Py_INCREF(mod_name);
7777db96d56Sopenharmony_ci        PyObject *spec = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__spec__));
7787db96d56Sopenharmony_ci        if (spec == NULL && PyErr_Occurred()) {
7797db96d56Sopenharmony_ci            Py_DECREF(mod_name);
7807db96d56Sopenharmony_ci            return NULL;
7817db96d56Sopenharmony_ci        }
7827db96d56Sopenharmony_ci        Py_XINCREF(spec);
7837db96d56Sopenharmony_ci        if (_PyModuleSpec_IsInitializing(spec)) {
7847db96d56Sopenharmony_ci            PyErr_Format(PyExc_AttributeError,
7857db96d56Sopenharmony_ci                            "partially initialized "
7867db96d56Sopenharmony_ci                            "module '%U' has no attribute '%U' "
7877db96d56Sopenharmony_ci                            "(most likely due to a circular import)",
7887db96d56Sopenharmony_ci                            mod_name, name);
7897db96d56Sopenharmony_ci        }
7907db96d56Sopenharmony_ci        else if (_PyModuleSpec_IsUninitializedSubmodule(spec, name)) {
7917db96d56Sopenharmony_ci            PyErr_Format(PyExc_AttributeError,
7927db96d56Sopenharmony_ci                            "cannot access submodule '%U' of module '%U' "
7937db96d56Sopenharmony_ci                            "(most likely due to a circular import)",
7947db96d56Sopenharmony_ci                            name, mod_name);
7957db96d56Sopenharmony_ci        }
7967db96d56Sopenharmony_ci        else {
7977db96d56Sopenharmony_ci            PyErr_Format(PyExc_AttributeError,
7987db96d56Sopenharmony_ci                            "module '%U' has no attribute '%U'",
7997db96d56Sopenharmony_ci                            mod_name, name);
8007db96d56Sopenharmony_ci        }
8017db96d56Sopenharmony_ci        Py_XDECREF(spec);
8027db96d56Sopenharmony_ci        Py_DECREF(mod_name);
8037db96d56Sopenharmony_ci        return NULL;
8047db96d56Sopenharmony_ci    }
8057db96d56Sopenharmony_ci    else if (PyErr_Occurred()) {
8067db96d56Sopenharmony_ci        return NULL;
8077db96d56Sopenharmony_ci    }
8087db96d56Sopenharmony_ci    PyErr_Format(PyExc_AttributeError,
8097db96d56Sopenharmony_ci                "module has no attribute '%U'", name);
8107db96d56Sopenharmony_ci    return NULL;
8117db96d56Sopenharmony_ci}
8127db96d56Sopenharmony_ci
8137db96d56Sopenharmony_cistatic int
8147db96d56Sopenharmony_cimodule_traverse(PyModuleObject *m, visitproc visit, void *arg)
8157db96d56Sopenharmony_ci{
8167db96d56Sopenharmony_ci    /* bpo-39824: Don't call m_traverse() if m_size > 0 and md_state=NULL */
8177db96d56Sopenharmony_ci    if (m->md_def && m->md_def->m_traverse
8187db96d56Sopenharmony_ci        && (m->md_def->m_size <= 0 || m->md_state != NULL))
8197db96d56Sopenharmony_ci    {
8207db96d56Sopenharmony_ci        int res = m->md_def->m_traverse((PyObject*)m, visit, arg);
8217db96d56Sopenharmony_ci        if (res)
8227db96d56Sopenharmony_ci            return res;
8237db96d56Sopenharmony_ci    }
8247db96d56Sopenharmony_ci    Py_VISIT(m->md_dict);
8257db96d56Sopenharmony_ci    return 0;
8267db96d56Sopenharmony_ci}
8277db96d56Sopenharmony_ci
8287db96d56Sopenharmony_cistatic int
8297db96d56Sopenharmony_cimodule_clear(PyModuleObject *m)
8307db96d56Sopenharmony_ci{
8317db96d56Sopenharmony_ci    /* bpo-39824: Don't call m_clear() if m_size > 0 and md_state=NULL */
8327db96d56Sopenharmony_ci    if (m->md_def && m->md_def->m_clear
8337db96d56Sopenharmony_ci        && (m->md_def->m_size <= 0 || m->md_state != NULL))
8347db96d56Sopenharmony_ci    {
8357db96d56Sopenharmony_ci        int res = m->md_def->m_clear((PyObject*)m);
8367db96d56Sopenharmony_ci        if (PyErr_Occurred()) {
8377db96d56Sopenharmony_ci            PySys_FormatStderr("Exception ignored in m_clear of module%s%V\n",
8387db96d56Sopenharmony_ci                               m->md_name ? " " : "",
8397db96d56Sopenharmony_ci                               m->md_name, "");
8407db96d56Sopenharmony_ci            PyErr_WriteUnraisable(NULL);
8417db96d56Sopenharmony_ci        }
8427db96d56Sopenharmony_ci        if (res)
8437db96d56Sopenharmony_ci            return res;
8447db96d56Sopenharmony_ci    }
8457db96d56Sopenharmony_ci    Py_CLEAR(m->md_dict);
8467db96d56Sopenharmony_ci    return 0;
8477db96d56Sopenharmony_ci}
8487db96d56Sopenharmony_ci
8497db96d56Sopenharmony_cistatic PyObject *
8507db96d56Sopenharmony_cimodule_dir(PyObject *self, PyObject *args)
8517db96d56Sopenharmony_ci{
8527db96d56Sopenharmony_ci    PyObject *result = NULL;
8537db96d56Sopenharmony_ci    PyObject *dict = PyObject_GetAttr(self, &_Py_ID(__dict__));
8547db96d56Sopenharmony_ci
8557db96d56Sopenharmony_ci    if (dict != NULL) {
8567db96d56Sopenharmony_ci        if (PyDict_Check(dict)) {
8577db96d56Sopenharmony_ci            PyObject *dirfunc = PyDict_GetItemWithError(dict, &_Py_ID(__dir__));
8587db96d56Sopenharmony_ci            if (dirfunc) {
8597db96d56Sopenharmony_ci                result = _PyObject_CallNoArgs(dirfunc);
8607db96d56Sopenharmony_ci            }
8617db96d56Sopenharmony_ci            else if (!PyErr_Occurred()) {
8627db96d56Sopenharmony_ci                result = PyDict_Keys(dict);
8637db96d56Sopenharmony_ci            }
8647db96d56Sopenharmony_ci        }
8657db96d56Sopenharmony_ci        else {
8667db96d56Sopenharmony_ci            PyErr_Format(PyExc_TypeError, "<module>.__dict__ is not a dictionary");
8677db96d56Sopenharmony_ci        }
8687db96d56Sopenharmony_ci    }
8697db96d56Sopenharmony_ci
8707db96d56Sopenharmony_ci    Py_XDECREF(dict);
8717db96d56Sopenharmony_ci    return result;
8727db96d56Sopenharmony_ci}
8737db96d56Sopenharmony_ci
8747db96d56Sopenharmony_cistatic PyMethodDef module_methods[] = {
8757db96d56Sopenharmony_ci    {"__dir__", module_dir, METH_NOARGS,
8767db96d56Sopenharmony_ci     PyDoc_STR("__dir__() -> list\nspecialized dir() implementation")},
8777db96d56Sopenharmony_ci    {0}
8787db96d56Sopenharmony_ci};
8797db96d56Sopenharmony_ci
8807db96d56Sopenharmony_cistatic PyObject *
8817db96d56Sopenharmony_cimodule_get_annotations(PyModuleObject *m, void *Py_UNUSED(ignored))
8827db96d56Sopenharmony_ci{
8837db96d56Sopenharmony_ci    PyObject *dict = PyObject_GetAttr((PyObject *)m, &_Py_ID(__dict__));
8847db96d56Sopenharmony_ci
8857db96d56Sopenharmony_ci    if ((dict == NULL) || !PyDict_Check(dict)) {
8867db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError, "<module>.__dict__ is not a dictionary");
8877db96d56Sopenharmony_ci        Py_XDECREF(dict);
8887db96d56Sopenharmony_ci        return NULL;
8897db96d56Sopenharmony_ci    }
8907db96d56Sopenharmony_ci
8917db96d56Sopenharmony_ci    PyObject *annotations;
8927db96d56Sopenharmony_ci    /* there's no _PyDict_GetItemId without WithError, so let's LBYL. */
8937db96d56Sopenharmony_ci    if (PyDict_Contains(dict, &_Py_ID(__annotations__))) {
8947db96d56Sopenharmony_ci        annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__));
8957db96d56Sopenharmony_ci        /*
8967db96d56Sopenharmony_ci        ** _PyDict_GetItemIdWithError could still fail,
8977db96d56Sopenharmony_ci        ** for instance with a well-timed Ctrl-C or a MemoryError.
8987db96d56Sopenharmony_ci        ** so let's be totally safe.
8997db96d56Sopenharmony_ci        */
9007db96d56Sopenharmony_ci        if (annotations) {
9017db96d56Sopenharmony_ci            Py_INCREF(annotations);
9027db96d56Sopenharmony_ci        }
9037db96d56Sopenharmony_ci    } else {
9047db96d56Sopenharmony_ci        annotations = PyDict_New();
9057db96d56Sopenharmony_ci        if (annotations) {
9067db96d56Sopenharmony_ci            int result = PyDict_SetItem(
9077db96d56Sopenharmony_ci                    dict, &_Py_ID(__annotations__), annotations);
9087db96d56Sopenharmony_ci            if (result) {
9097db96d56Sopenharmony_ci                Py_CLEAR(annotations);
9107db96d56Sopenharmony_ci            }
9117db96d56Sopenharmony_ci        }
9127db96d56Sopenharmony_ci    }
9137db96d56Sopenharmony_ci    Py_DECREF(dict);
9147db96d56Sopenharmony_ci    return annotations;
9157db96d56Sopenharmony_ci}
9167db96d56Sopenharmony_ci
9177db96d56Sopenharmony_cistatic int
9187db96d56Sopenharmony_cimodule_set_annotations(PyModuleObject *m, PyObject *value, void *Py_UNUSED(ignored))
9197db96d56Sopenharmony_ci{
9207db96d56Sopenharmony_ci    int ret = -1;
9217db96d56Sopenharmony_ci    PyObject *dict = PyObject_GetAttr((PyObject *)m, &_Py_ID(__dict__));
9227db96d56Sopenharmony_ci
9237db96d56Sopenharmony_ci    if ((dict == NULL) || !PyDict_Check(dict)) {
9247db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError, "<module>.__dict__ is not a dictionary");
9257db96d56Sopenharmony_ci        goto exit;
9267db96d56Sopenharmony_ci    }
9277db96d56Sopenharmony_ci
9287db96d56Sopenharmony_ci    if (value != NULL) {
9297db96d56Sopenharmony_ci        /* set */
9307db96d56Sopenharmony_ci        ret = PyDict_SetItem(dict, &_Py_ID(__annotations__), value);
9317db96d56Sopenharmony_ci        goto exit;
9327db96d56Sopenharmony_ci    }
9337db96d56Sopenharmony_ci
9347db96d56Sopenharmony_ci    /* delete */
9357db96d56Sopenharmony_ci    if (!PyDict_Contains(dict, &_Py_ID(__annotations__))) {
9367db96d56Sopenharmony_ci        PyErr_Format(PyExc_AttributeError, "__annotations__");
9377db96d56Sopenharmony_ci        goto exit;
9387db96d56Sopenharmony_ci    }
9397db96d56Sopenharmony_ci
9407db96d56Sopenharmony_ci    ret = PyDict_DelItem(dict, &_Py_ID(__annotations__));
9417db96d56Sopenharmony_ci
9427db96d56Sopenharmony_ciexit:
9437db96d56Sopenharmony_ci    Py_XDECREF(dict);
9447db96d56Sopenharmony_ci    return ret;
9457db96d56Sopenharmony_ci}
9467db96d56Sopenharmony_ci
9477db96d56Sopenharmony_ci
9487db96d56Sopenharmony_cistatic PyGetSetDef module_getsets[] = {
9497db96d56Sopenharmony_ci    {"__annotations__", (getter)module_get_annotations, (setter)module_set_annotations},
9507db96d56Sopenharmony_ci    {NULL}
9517db96d56Sopenharmony_ci};
9527db96d56Sopenharmony_ci
9537db96d56Sopenharmony_ciPyTypeObject PyModule_Type = {
9547db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
9557db96d56Sopenharmony_ci    "module",                                   /* tp_name */
9567db96d56Sopenharmony_ci    sizeof(PyModuleObject),                     /* tp_basicsize */
9577db96d56Sopenharmony_ci    0,                                          /* tp_itemsize */
9587db96d56Sopenharmony_ci    (destructor)module_dealloc,                 /* tp_dealloc */
9597db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
9607db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
9617db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
9627db96d56Sopenharmony_ci    0,                                          /* tp_as_async */
9637db96d56Sopenharmony_ci    (reprfunc)module_repr,                      /* tp_repr */
9647db96d56Sopenharmony_ci    0,                                          /* tp_as_number */
9657db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
9667db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
9677db96d56Sopenharmony_ci    0,                                          /* tp_hash */
9687db96d56Sopenharmony_ci    0,                                          /* tp_call */
9697db96d56Sopenharmony_ci    0,                                          /* tp_str */
9707db96d56Sopenharmony_ci    (getattrofunc)module_getattro,              /* tp_getattro */
9717db96d56Sopenharmony_ci    PyObject_GenericSetAttr,                    /* tp_setattro */
9727db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
9737db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
9747db96d56Sopenharmony_ci        Py_TPFLAGS_BASETYPE,                    /* tp_flags */
9757db96d56Sopenharmony_ci    module___init____doc__,                     /* tp_doc */
9767db96d56Sopenharmony_ci    (traverseproc)module_traverse,              /* tp_traverse */
9777db96d56Sopenharmony_ci    (inquiry)module_clear,                      /* tp_clear */
9787db96d56Sopenharmony_ci    0,                                          /* tp_richcompare */
9797db96d56Sopenharmony_ci    offsetof(PyModuleObject, md_weaklist),      /* tp_weaklistoffset */
9807db96d56Sopenharmony_ci    0,                                          /* tp_iter */
9817db96d56Sopenharmony_ci    0,                                          /* tp_iternext */
9827db96d56Sopenharmony_ci    module_methods,                             /* tp_methods */
9837db96d56Sopenharmony_ci    module_members,                             /* tp_members */
9847db96d56Sopenharmony_ci    module_getsets,                             /* tp_getset */
9857db96d56Sopenharmony_ci    0,                                          /* tp_base */
9867db96d56Sopenharmony_ci    0,                                          /* tp_dict */
9877db96d56Sopenharmony_ci    0,                                          /* tp_descr_get */
9887db96d56Sopenharmony_ci    0,                                          /* tp_descr_set */
9897db96d56Sopenharmony_ci    offsetof(PyModuleObject, md_dict),          /* tp_dictoffset */
9907db96d56Sopenharmony_ci    module___init__,                            /* tp_init */
9917db96d56Sopenharmony_ci    0,                                          /* tp_alloc */
9927db96d56Sopenharmony_ci    new_module,                                 /* tp_new */
9937db96d56Sopenharmony_ci    PyObject_GC_Del,                            /* tp_free */
9947db96d56Sopenharmony_ci};
995