Merged release21-maint changes.
[python/dscho.git] / Objects / moduleobject.c
blob7faa3bbfd3e656a2de36bd95729f02ae884f0919
2 /* Module object implementation */
4 #include "Python.h"
5 #include "structmember.h"
7 typedef struct {
8 PyObject_HEAD
9 PyObject *md_dict;
10 } PyModuleObject;
12 struct memberlist module_members[] = {
13 {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
14 {0}
17 PyObject *
18 PyModule_New(char *name)
20 PyModuleObject *m;
21 PyObject *nameobj;
22 m = PyObject_NEW(PyModuleObject, &PyModule_Type);
23 if (m == NULL)
24 return NULL;
25 nameobj = PyString_FromString(name);
26 m->md_dict = PyDict_New();
27 PyObject_GC_Init(m);
28 if (m->md_dict == NULL || nameobj == NULL)
29 goto fail;
30 if (PyDict_SetItemString(m->md_dict, "__name__", nameobj) != 0)
31 goto fail;
32 if (PyDict_SetItemString(m->md_dict, "__doc__", Py_None) != 0)
33 goto fail;
34 Py_DECREF(nameobj);
35 return (PyObject *)m;
37 fail:
38 Py_XDECREF(nameobj);
39 Py_DECREF(m);
40 return NULL;
43 PyObject *
44 PyModule_GetDict(PyObject *m)
46 if (!PyModule_Check(m)) {
47 PyErr_BadInternalCall();
48 return NULL;
50 return ((PyModuleObject *)m) -> md_dict;
53 char *
54 PyModule_GetName(PyObject *m)
56 PyObject *nameobj;
57 if (!PyModule_Check(m)) {
58 PyErr_BadArgument();
59 return NULL;
61 nameobj = PyDict_GetItemString(((PyModuleObject *)m)->md_dict,
62 "__name__");
63 if (nameobj == NULL || !PyString_Check(nameobj)) {
64 PyErr_SetString(PyExc_SystemError, "nameless module");
65 return NULL;
67 return PyString_AsString(nameobj);
70 char *
71 PyModule_GetFilename(PyObject *m)
73 PyObject *fileobj;
74 if (!PyModule_Check(m)) {
75 PyErr_BadArgument();
76 return NULL;
78 fileobj = PyDict_GetItemString(((PyModuleObject *)m)->md_dict,
79 "__file__");
80 if (fileobj == NULL || !PyString_Check(fileobj)) {
81 PyErr_SetString(PyExc_SystemError, "module filename missing");
82 return NULL;
84 return PyString_AsString(fileobj);
87 void
88 _PyModule_Clear(PyObject *m)
90 /* To make the execution order of destructors for global
91 objects a bit more predictable, we first zap all objects
92 whose name starts with a single underscore, before we clear
93 the entire dictionary. We zap them by replacing them with
94 None, rather than deleting them from the dictionary, to
95 avoid rehashing the dictionary (to some extent). */
97 int pos;
98 PyObject *key, *value;
99 PyObject *d;
101 d = ((PyModuleObject *)m)->md_dict;
103 /* First, clear only names starting with a single underscore */
104 pos = 0;
105 while (PyDict_Next(d, &pos, &key, &value)) {
106 if (value != Py_None && PyString_Check(key)) {
107 char *s = PyString_AsString(key);
108 if (s[0] == '_' && s[1] != '_') {
109 if (Py_VerboseFlag > 1)
110 PySys_WriteStderr("# clear[1] %s\n", s);
111 PyDict_SetItem(d, key, Py_None);
116 /* Next, clear all names except for __builtins__ */
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] != '_' || strcmp(s, "__builtins__") != 0) {
122 if (Py_VerboseFlag > 1)
123 PySys_WriteStderr("# clear[2] %s\n", s);
124 PyDict_SetItem(d, key, Py_None);
129 /* Note: we leave __builtins__ in place, so that destructors
130 of non-global objects defined in this module can still use
131 builtins, in particularly 'None'. */
135 /* Methods */
137 static int
138 module_init(PyModuleObject *m, PyObject *args, PyObject *kw)
140 m->md_dict = PyDict_New();
141 if (m->md_dict == NULL)
142 return -1;
143 return 0;
146 static void
147 module_dealloc(PyModuleObject *m)
149 PyObject_GC_Fini(m);
150 if (m->md_dict != NULL) {
151 _PyModule_Clear((PyObject *)m);
152 Py_DECREF(m->md_dict);
154 PyObject_DEL(PyObject_AS_GC(m));
157 static PyObject *
158 module_repr(PyModuleObject *m)
160 char buf[400];
161 char *name;
162 char *filename;
163 name = PyModule_GetName((PyObject *)m);
164 if (name == NULL) {
165 PyErr_Clear();
166 name = "?";
168 filename = PyModule_GetFilename((PyObject *)m);
169 if (filename == NULL) {
170 PyErr_Clear();
171 sprintf(buf, "<module '%.80s' (built-in)>", name);
172 } else {
173 sprintf(buf, "<module '%.80s' from '%.255s'>", name, filename);
176 return PyString_FromString(buf);
179 /* We only need a traverse function, no clear function: If the module
180 is in a cycle, md_dict will be cleared as well, which will break
181 the cycle. */
182 static int
183 module_traverse(PyModuleObject *m, visitproc visit, void *arg)
185 if (m->md_dict != NULL)
186 return visit(m->md_dict, arg);
187 return 0;
190 PyTypeObject PyModule_Type = {
191 PyObject_HEAD_INIT(&PyType_Type)
192 0, /* ob_size */
193 "module", /* tp_name */
194 sizeof(PyModuleObject) + PyGC_HEAD_SIZE, /* tp_size */
195 0, /* tp_itemsize */
196 (destructor)module_dealloc, /* tp_dealloc */
197 0, /* tp_print */
198 0, /* tp_getattr */
199 0, /* tp_setattr */
200 0, /* tp_compare */
201 (reprfunc)module_repr, /* tp_repr */
202 0, /* tp_as_number */
203 0, /* tp_as_sequence */
204 0, /* tp_as_mapping */
205 0, /* tp_hash */
206 0, /* tp_call */
207 0, /* tp_str */
208 PyObject_GenericGetAttr, /* tp_getattro */
209 PyObject_GenericSetAttr, /* tp_setattro */
210 0, /* tp_as_buffer */
211 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC |
212 Py_TPFLAGS_BASETYPE, /* tp_flags */
213 0, /* tp_doc */
214 (traverseproc)module_traverse, /* tp_traverse */
215 0, /* tp_clear */
216 0, /* tp_richcompare */
217 0, /* tp_weaklistoffset */
218 0, /* tp_iter */
219 0, /* tp_iternext */
220 0, /* tp_methods */
221 module_members, /* tp_members */
222 0, /* tp_getset */
223 0, /* tp_base */
224 0, /* tp_dict */
225 0, /* tp_descr_get */
226 0, /* tp_descr_set */
227 offsetof(PyModuleObject, md_dict), /* tp_dictoffset */
228 (initproc)module_init, /* tp_init */
229 PyType_GenericAlloc, /* tp_alloc */
230 PyType_GenericNew, /* tp_new */