diff options
Diffstat (limited to 'Objects/moduleobject.c')
-rw-r--r-- | Objects/moduleobject.c | 62 |
1 files changed, 44 insertions, 18 deletions
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 2f2bd36..3ea3be8 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -11,6 +11,8 @@ typedef struct { PyObject *md_dict; struct PyModuleDef *md_def; void *md_state; + PyObject *md_weaklist; + PyObject *md_name; /* for logging purposes after md_dict is cleared */ } PyModuleObject; static PyMemberDef module_members[] = { @@ -26,6 +28,33 @@ static PyTypeObject moduledef_type = { }; +static int +module_init_dict(PyModuleObject *mod, PyObject *md_dict, + PyObject *name, PyObject *doc) +{ + if (md_dict == NULL) + return -1; + if (doc == NULL) + doc = Py_None; + + if (PyDict_SetItemString(md_dict, "__name__", name) != 0) + return -1; + if (PyDict_SetItemString(md_dict, "__doc__", doc) != 0) + return -1; + if (PyDict_SetItemString(md_dict, "__package__", Py_None) != 0) + return -1; + if (PyDict_SetItemString(md_dict, "__loader__", Py_None) != 0) + return -1; + if (PyUnicode_CheckExact(name)) { + Py_INCREF(name); + Py_XDECREF(mod->md_name); + mod->md_name = name; + } + + return 0; +} + + PyObject * PyModule_NewObject(PyObject *name) { @@ -35,14 +64,10 @@ PyModule_NewObject(PyObject *name) return NULL; m->md_def = NULL; m->md_state = NULL; + m->md_weaklist = NULL; + m->md_name = NULL; m->md_dict = PyDict_New(); - if (m->md_dict == NULL) - goto fail; - if (PyDict_SetItemString(m->md_dict, "__name__", name) != 0) - goto fail; - if (PyDict_SetItemString(m->md_dict, "__doc__", Py_None) != 0) - goto fail; - if (PyDict_SetItemString(m->md_dict, "__package__", Py_None) != 0) + if (module_init_dict(m, m->md_dict, name, NULL) != 0) goto fail; PyObject_GC_Track(m); return (PyObject *)m; @@ -347,9 +372,7 @@ module_init(PyModuleObject *m, PyObject *args, PyObject *kwds) return -1; m->md_dict = dict; } - if (PyDict_SetItemString(dict, "__name__", name) < 0) - return -1; - if (PyDict_SetItemString(dict, "__doc__", doc) < 0) + if (module_init_dict(m, dict, name, doc) < 0) return -1; return 0; } @@ -358,12 +381,15 @@ static void module_dealloc(PyModuleObject *m) { PyObject_GC_UnTrack(m); + if (Py_VerboseFlag && m->md_name) { + PySys_FormatStderr("# destroy %S\n", m->md_name); + } + if (m->md_weaklist != NULL) + PyObject_ClearWeakRefs((PyObject *) m); if (m->md_def && m->md_def->m_free) m->md_def->m_free(m); - if (m->md_dict != NULL) { - _PyModule_Clear((PyObject *)m); - Py_DECREF(m->md_dict); - } + Py_XDECREF(m->md_dict); + Py_XDECREF(m->md_name); if (m->md_state != NULL) PyMem_FREE(m->md_state); Py_TYPE(m)->tp_free((PyObject *)m); @@ -380,7 +406,7 @@ module_repr(PyModuleObject *m) if (m->md_dict != NULL) { loader = PyDict_GetItemString(m->md_dict, "__loader__"); } - if (loader != NULL) { + if (loader != NULL && loader != Py_None) { repr = PyObject_CallMethod(loader, "module_repr", "(O)", (PyObject *)m, NULL); if (repr == NULL) { @@ -404,10 +430,10 @@ module_repr(PyModuleObject *m) filename = PyModule_GetFilenameObject((PyObject *)m); if (filename == NULL) { PyErr_Clear(); - /* There's no m.__file__, so if there was an __loader__, use that in + /* There's no m.__file__, so if there was a __loader__, use that in * the repr, otherwise, the only thing you can use is m.__name__ */ - if (loader == NULL) { + if (loader == NULL || loader == Py_None) { repr = PyUnicode_FromFormat("<module %R>", name); } else { @@ -509,7 +535,7 @@ PyTypeObject PyModule_Type = { (traverseproc)module_traverse, /* tp_traverse */ (inquiry)module_clear, /* tp_clear */ 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ + offsetof(PyModuleObject, md_weaklist), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ module_methods, /* tp_methods */ |