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

Last change on this file was 388, checked in by dmik, 11 years ago

python: Update vendor to 2.7.6.

  • Property svn:eol-style set to native
File size: 8.1 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 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 PyDict_SetItem(d, key, Py_None);
126 }
127 }
128 }
129
130 /* Next, clear all names except for __builtins__ */
131 pos = 0;
132 while (PyDict_Next(d, &pos, &key, &value)) {
133 if (value != Py_None && PyString_Check(key)) {
134 char *s = PyString_AsString(key);
135 if (s[0] != '_' || strcmp(s, "__builtins__") != 0) {
136 if (Py_VerboseFlag > 1)
137 PySys_WriteStderr("# clear[2] %s\n", s);
138 PyDict_SetItem(d, key, Py_None);
139 }
140 }
141 }
142
143 /* Note: we leave __builtins__ in place, so that destructors
144 of non-global objects defined in this module can still use
145 builtins, in particularly 'None'. */
146
147}
148
149/* Methods */
150
151static int
152module_init(PyModuleObject *m, PyObject *args, PyObject *kwds)
153{
154 static char *kwlist[] = {"name", "doc", NULL};
155 PyObject *dict, *name = Py_None, *doc = Py_None;
156 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S|O:module.__init__",
157 kwlist, &name, &doc))
158 return -1;
159 dict = m->md_dict;
160 if (dict == NULL) {
161 dict = PyDict_New();
162 if (dict == NULL)
163 return -1;
164 m->md_dict = dict;
165 }
166 if (PyDict_SetItemString(dict, "__name__", name) < 0)
167 return -1;
168 if (PyDict_SetItemString(dict, "__doc__", doc) < 0)
169 return -1;
170 return 0;
171}
172
173static void
174module_dealloc(PyModuleObject *m)
175{
176 PyObject_GC_UnTrack(m);
177 if (m->md_dict != NULL) {
178 _PyModule_Clear((PyObject *)m);
179 Py_DECREF(m->md_dict);
180 }
181 Py_TYPE(m)->tp_free((PyObject *)m);
182}
183
184static PyObject *
185module_repr(PyModuleObject *m)
186{
187 char *name;
188 char *filename;
189
190 name = PyModule_GetName((PyObject *)m);
191 if (name == NULL) {
192 PyErr_Clear();
193 name = "?";
194 }
195 filename = PyModule_GetFilename((PyObject *)m);
196 if (filename == NULL) {
197 PyErr_Clear();
198 return PyString_FromFormat("<module '%s' (built-in)>", name);
199 }
200 return PyString_FromFormat("<module '%s' from '%s'>", name, filename);
201}
202
203/* We only need a traverse function, no clear function: If the module
204 is in a cycle, md_dict will be cleared as well, which will break
205 the cycle. */
206static int
207module_traverse(PyModuleObject *m, visitproc visit, void *arg)
208{
209 Py_VISIT(m->md_dict);
210 return 0;
211}
212
213PyDoc_STRVAR(module_doc,
214"module(name[, doc])\n\
215\n\
216Create a module object.\n\
217The name must be a string; the optional doc argument can have any type.");
218
219PyTypeObject PyModule_Type = {
220 PyVarObject_HEAD_INIT(&PyType_Type, 0)
221 "module", /* tp_name */
222 sizeof(PyModuleObject), /* tp_size */
223 0, /* tp_itemsize */
224 (destructor)module_dealloc, /* tp_dealloc */
225 0, /* tp_print */
226 0, /* tp_getattr */
227 0, /* tp_setattr */
228 0, /* tp_compare */
229 (reprfunc)module_repr, /* tp_repr */
230 0, /* tp_as_number */
231 0, /* tp_as_sequence */
232 0, /* tp_as_mapping */
233 0, /* tp_hash */
234 0, /* tp_call */
235 0, /* tp_str */
236 PyObject_GenericGetAttr, /* tp_getattro */
237 PyObject_GenericSetAttr, /* tp_setattro */
238 0, /* tp_as_buffer */
239 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
240 Py_TPFLAGS_BASETYPE, /* tp_flags */
241 module_doc, /* tp_doc */
242 (traverseproc)module_traverse, /* tp_traverse */
243 0, /* tp_clear */
244 0, /* tp_richcompare */
245 0, /* tp_weaklistoffset */
246 0, /* tp_iter */
247 0, /* tp_iternext */
248 0, /* tp_methods */
249 module_members, /* tp_members */
250 0, /* tp_getset */
251 0, /* tp_base */
252 0, /* tp_dict */
253 0, /* tp_descr_get */
254 0, /* tp_descr_set */
255 offsetof(PyModuleObject, md_dict), /* tp_dictoffset */
256 (initproc)module_init, /* tp_init */
257 PyType_GenericAlloc, /* tp_alloc */
258 PyType_GenericNew, /* tp_new */
259 PyObject_GC_Del, /* tp_free */
260};
Note: See TracBrowser for help on using the repository browser.