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