PageRenderTime 539ms CodeModel.GetById 177ms app.highlight 141ms RepoModel.GetById 147ms app.codeStats 0ms

/Objects/moduleobject.c

http://unladen-swallow.googlecode.com/
C | 260 lines | 220 code | 24 blank | 16 comment | 56 complexity | e2fd824941911811ea0f7c7175aadec4 MD5 | raw file
  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};