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