source: vendor/python/2.5/Objects/moduleobject.c

Last change on this file was 3225, checked in by bird, 18 years ago

Python 2.5

File size: 6.2 KB
Line 
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};
Note: See TracBrowser for help on using the repository browser.