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