moduleobject.c revision 49fd7fa4431da299196d74087df4a04f99f9c46f
1 2/* Module object implementation */ 3 4#include "Python.h" 5#include "structmember.h" 6 7typedef struct { 8 PyObject_HEAD 9 PyObject *md_dict; 10} PyModuleObject; 11 12static PyMemberDef module_members[] = { 13 {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY}, 14 {0} 15}; 16 17PyObject * 18PyModule_New(const char *name) 19{ 20 PyModuleObject *m; 21 PyObject *nameobj; 22 m = PyObject_GC_New(PyModuleObject, &PyModule_Type); 23 if (m == NULL) 24 return NULL; 25 nameobj = PyString_FromString(name); 26 m->md_dict = PyDict_New(); 27 if (m->md_dict == NULL || nameobj == NULL) 28 goto fail; 29 if (PyDict_SetItemString(m->md_dict, "__name__", nameobj) != 0) 30 goto fail; 31 if (PyDict_SetItemString(m->md_dict, "__doc__", Py_None) != 0) 32 goto fail; 33 Py_DECREF(nameobj); 34 PyObject_GC_Track(m); 35 return (PyObject *)m; 36 37 fail: 38 Py_XDECREF(nameobj); 39 Py_DECREF(m); 40 return NULL; 41} 42 43PyObject * 44PyModule_GetDict(PyObject *m) 45{ 46 PyObject *d; 47 if (!PyModule_Check(m)) { 48 PyErr_BadInternalCall(); 49 return NULL; 50 } 51 d = ((PyModuleObject *)m) -> md_dict; 52 if (d == NULL) 53 ((PyModuleObject *)m) -> md_dict = d = PyDict_New(); 54 return d; 55} 56 57char * 58PyModule_GetName(PyObject *m) 59{ 60 PyObject *d; 61 PyObject *nameobj; 62 if (!PyModule_Check(m)) { 63 PyErr_BadArgument(); 64 return NULL; 65 } 66 d = ((PyModuleObject *)m)->md_dict; 67 if (d == NULL || 68 (nameobj = PyDict_GetItemString(d, "__name__")) == NULL || 69 !PyString_Check(nameobj)) 70 { 71 PyErr_SetString(PyExc_SystemError, "nameless module"); 72 return NULL; 73 } 74 return PyString_AsString(nameobj); 75} 76 77char * 78PyModule_GetFilename(PyObject *m) 79{ 80 PyObject *d; 81 PyObject *fileobj; 82 if (!PyModule_Check(m)) { 83 PyErr_BadArgument(); 84 return NULL; 85 } 86 d = ((PyModuleObject *)m)->md_dict; 87 if (d == NULL || 88 (fileobj = PyDict_GetItemString(d, "__file__")) == NULL || 89 !PyString_Check(fileobj)) 90 { 91 PyErr_SetString(PyExc_SystemError, "module filename missing"); 92 return NULL; 93 } 94 return PyString_AsString(fileobj); 95} 96 97void 98_PyModule_Clear(PyObject *m) 99{ 100 /* To make the execution order of destructors for global 101 objects a bit more predictable, we first zap all objects 102 whose name starts with a single underscore, before we clear 103 the entire dictionary. We zap them by replacing them with 104 None, rather than deleting them from the dictionary, to 105 avoid rehashing the dictionary (to some extent). */ 106 107 Py_ssize_t pos; 108 PyObject *key, *value; 109 PyObject *d; 110 111 d = ((PyModuleObject *)m)->md_dict; 112 if (d == NULL) 113 return; 114 115 /* First, clear only names starting with a single underscore */ 116 pos = 0; 117 while (PyDict_Next(d, &pos, &key, &value)) { 118 if (value != Py_None && PyString_Check(key)) { 119 char *s = PyString_AsString(key); 120 if (s[0] == '_' && s[1] != '_') { 121 if (Py_VerboseFlag > 1) 122 PySys_WriteStderr("# clear[1] %s\n", s); 123 PyDict_SetItem(d, key, Py_None); 124 } 125 } 126 } 127 128 /* Next, clear all names except for __builtins__ */ 129 pos = 0; 130 while (PyDict_Next(d, &pos, &key, &value)) { 131 if (value != Py_None && PyString_Check(key)) { 132 char *s = PyString_AsString(key); 133 if (s[0] != '_' || strcmp(s, "__builtins__") != 0) { 134 if (Py_VerboseFlag > 1) 135 PySys_WriteStderr("# clear[2] %s\n", s); 136 PyDict_SetItem(d, key, Py_None); 137 } 138 } 139 } 140 141 /* Note: we leave __builtins__ in place, so that destructors 142 of non-global objects defined in this module can still use 143 builtins, in particularly 'None'. */ 144 145} 146 147/* Methods */ 148 149static int 150module_init(PyModuleObject *m, PyObject *args, PyObject *kwds) 151{ 152 static char *kwlist[] = {"name", "doc", NULL}; 153 PyObject *dict, *name = Py_None, *doc = Py_None; 154 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S|O:module.__init__", 155 kwlist, &name, &doc)) 156 return -1; 157 dict = m->md_dict; 158 if (dict == NULL) { 159 dict = PyDict_New(); 160 if (dict == NULL) 161 return -1; 162 m->md_dict = dict; 163 } 164 if (PyDict_SetItemString(dict, "__name__", name) < 0) 165 return -1; 166 if (PyDict_SetItemString(dict, "__doc__", doc) < 0) 167 return -1; 168 return 0; 169} 170 171static void 172module_dealloc(PyModuleObject *m) 173{ 174 PyObject_GC_UnTrack(m); 175 if (m->md_dict != NULL) { 176 _PyModule_Clear((PyObject *)m); 177 Py_DECREF(m->md_dict); 178 } 179 m->ob_type->tp_free((PyObject *)m); 180} 181 182static PyObject * 183module_repr(PyModuleObject *m) 184{ 185 char *name; 186 char *filename; 187 188 name = PyModule_GetName((PyObject *)m); 189 if (name == NULL) { 190 PyErr_Clear(); 191 name = "?"; 192 } 193 filename = PyModule_GetFilename((PyObject *)m); 194 if (filename == NULL) { 195 PyErr_Clear(); 196 return PyString_FromFormat("<module '%s' (built-in)>", name); 197 } 198 return PyString_FromFormat("<module '%s' from '%s'>", name, filename); 199} 200 201/* We only need a traverse function, no clear function: If the module 202 is in a cycle, md_dict will be cleared as well, which will break 203 the cycle. */ 204static int 205module_traverse(PyModuleObject *m, visitproc visit, void *arg) 206{ 207 Py_VISIT(m->md_dict); 208 return 0; 209} 210 211PyDoc_STRVAR(module_doc, 212"module(name[, doc])\n\ 213\n\ 214Create a module object.\n\ 215The name must be a string; the optional doc argument can have any type."); 216 217PyTypeObject PyModule_Type = { 218 PyObject_HEAD_INIT(&PyType_Type) 219 0, /* ob_size */ 220 "module", /* tp_name */ 221 sizeof(PyModuleObject), /* tp_size */ 222 0, /* tp_itemsize */ 223 (destructor)module_dealloc, /* tp_dealloc */ 224 0, /* tp_print */ 225 0, /* tp_getattr */ 226 0, /* tp_setattr */ 227 0, /* tp_compare */ 228 (reprfunc)module_repr, /* tp_repr */ 229 0, /* tp_as_number */ 230 0, /* tp_as_sequence */ 231 0, /* tp_as_mapping */ 232 0, /* tp_hash */ 233 0, /* tp_call */ 234 0, /* tp_str */ 235 PyObject_GenericGetAttr, /* tp_getattro */ 236 PyObject_GenericSetAttr, /* tp_setattro */ 237 0, /* tp_as_buffer */ 238 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 239 Py_TPFLAGS_BASETYPE, /* tp_flags */ 240 module_doc, /* tp_doc */ 241 (traverseproc)module_traverse, /* tp_traverse */ 242 0, /* tp_clear */ 243 0, /* tp_richcompare */ 244 0, /* tp_weaklistoffset */ 245 0, /* tp_iter */ 246 0, /* tp_iternext */ 247 0, /* tp_methods */ 248 module_members, /* tp_members */ 249 0, /* tp_getset */ 250 0, /* tp_base */ 251 0, /* tp_dict */ 252 0, /* tp_descr_get */ 253 0, /* tp_descr_set */ 254 offsetof(PyModuleObject, md_dict), /* tp_dictoffset */ 255 (initproc)module_init, /* tp_init */ 256 PyType_GenericAlloc, /* tp_alloc */ 257 PyType_GenericNew, /* tp_new */ 258 PyObject_GC_Del, /* tp_free */ 259}; 260