moduleobject.c revision 49fd7fa4431da299196d74087df4a04f99f9c46f
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};
260