1
2 /* Module object implementation */
3
4 #include "Python.h"
5 #include "structmember.h"
6
7 typedef struct {
8 PyObject_HEAD
9 PyObject *md_dict;
10 } PyModuleObject;
11
12 static PyMemberDef module_members[] = {
13 {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
14 {0}
15 };
16
17 PyObject *
PyModule_New(const char * name)18 PyModule_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
45 PyObject *
PyModule_GetDict(PyObject * m)46 PyModule_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
59 char *
PyModule_GetName(PyObject * m)60 PyModule_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
79 char *
PyModule_GetFilename(PyObject * m)80 PyModule_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
99 void
_PyModule_Clear(PyObject * m)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
153 static int
module_init(PyModuleObject * m,PyObject * args,PyObject * kwds)154 module_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
175 static void
module_dealloc(PyModuleObject * m)176 module_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
186 static PyObject *
module_repr(PyModuleObject * m)187 module_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. */
208 static int
module_traverse(PyModuleObject * m,visitproc visit,void * arg)209 module_traverse(PyModuleObject *m, visitproc visit, void *arg)
210 {
211 Py_VISIT(m->md_dict);
212 return 0;
213 }
214
215 PyDoc_STRVAR(module_doc,
216 "module(name[, doc])\n\
217 \n\
218 Create a module object.\n\
219 The name must be a string; the optional doc argument can have any type.");
220
221 PyTypeObject PyModule_Type = {
222 PyVarObject_HEAD_INIT(&PyType_Type, 0)
223 "module", /* tp_name */
224 sizeof(PyModuleObject), /* tp_basicsize */
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