moduleobject.c 6.16 KB
Newer Older
1

Guido van Rossum's avatar
Guido van Rossum committed
2 3
/* Module object implementation */

4
#include "Python.h"
5
#include "structmember.h"
Guido van Rossum's avatar
Guido van Rossum committed
6 7

typedef struct {
8 9 10
	PyObject_HEAD
	PyObject *md_dict;
} PyModuleObject;
Guido van Rossum's avatar
Guido van Rossum committed
11

12
static PyMemberDef module_members[] = {
13 14 15 16
	{"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
	{0}
};

17
PyObject *
18
PyModule_New(char *name)
Guido van Rossum's avatar
Guido van Rossum committed
19
{
20 21
	PyModuleObject *m;
	PyObject *nameobj;
Neil Schemenauer's avatar
Neil Schemenauer committed
22
	m = PyObject_GC_New(PyModuleObject, &PyModule_Type);
Guido van Rossum's avatar
Guido van Rossum committed
23 24
	if (m == NULL)
		return NULL;
25 26
	nameobj = PyString_FromString(name);
	m->md_dict = PyDict_New();
27 28
	if (m->md_dict == NULL || nameobj == NULL)
		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);
Neil Schemenauer's avatar
Neil Schemenauer committed
34
	PyObject_GC_Track(m);
35
	return (PyObject *)m;
36 37

 fail:
38 39
	Py_XDECREF(nameobj);
	Py_DECREF(m);
40
	return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
41 42
}

43
PyObject *
44
PyModule_GetDict(PyObject *m)
Guido van Rossum's avatar
Guido van Rossum committed
45
{
46
	PyObject *d;
47 48
	if (!PyModule_Check(m)) {
		PyErr_BadInternalCall();
Guido van Rossum's avatar
Guido van Rossum committed
49 50
		return NULL;
	}
51 52 53 54
	d = ((PyModuleObject *)m) -> md_dict;
	if (d == NULL)
		((PyModuleObject *)m) -> md_dict = d = PyDict_New();
	return d;
Guido van Rossum's avatar
Guido van Rossum committed
55 56
}

57
char *
58
PyModule_GetName(PyObject *m)
59
{
60
	PyObject *d;
61 62 63
	PyObject *nameobj;
	if (!PyModule_Check(m)) {
		PyErr_BadArgument();
64 65
		return NULL;
	}
66 67 68 69 70
	d = ((PyModuleObject *)m)->md_dict;
	if (d == NULL ||
	    (nameobj = PyDict_GetItemString(d, "__name__")) == NULL ||
	    !PyString_Check(nameobj))
	{
71
		PyErr_SetString(PyExc_SystemError, "nameless module");
72 73
		return NULL;
	}
74
	return PyString_AsString(nameobj);
75 76
}

77
char *
78
PyModule_GetFilename(PyObject *m)
79
{
80
	PyObject *d;
81 82 83 84 85
	PyObject *fileobj;
	if (!PyModule_Check(m)) {
		PyErr_BadArgument();
		return NULL;
	}
86 87 88 89 90
	d = ((PyModuleObject *)m)->md_dict;
	if (d == NULL ||
	    (fileobj = PyDict_GetItemString(d, "__file__")) == NULL ||
	    !PyString_Check(fileobj))
	{
91 92 93 94 95 96
		PyErr_SetString(PyExc_SystemError, "module filename missing");
		return NULL;
	}
	return PyString_AsString(fileobj);
}

97
void
98
_PyModule_Clear(PyObject *m)
99 100 101 102 103 104 105 106 107 108 109 110 111
{
	/* To make the execution order of destructors for global
	   objects a bit more predictable, we first zap all objects
	   whose name starts with a single underscore, before we clear
	   the entire dictionary.  We zap them by replacing them with
	   None, rather than deleting them from the dictionary, to
	   avoid rehashing the dictionary (to some extent). */

	int pos;
	PyObject *key, *value;
	PyObject *d;

	d = ((PyModuleObject *)m)->md_dict;
112 113
	if (d == NULL)
		return;
114 115 116 117 118 119 120 121

	/* First, clear only names starting with a single underscore */
	pos = 0;
	while (PyDict_Next(d, &pos, &key, &value)) {
		if (value != Py_None && PyString_Check(key)) {
			char *s = PyString_AsString(key);
			if (s[0] == '_' && s[1] != '_') {
				if (Py_VerboseFlag > 1)
122
				    PySys_WriteStderr("#   clear[1] %s\n", s);
123 124 125 126 127 128 129 130 131 132 133 134
				PyDict_SetItem(d, key, Py_None);
			}
		}
	}

	/* Next, clear all names except for __builtins__ */
	pos = 0;
	while (PyDict_Next(d, &pos, &key, &value)) {
		if (value != Py_None && PyString_Check(key)) {
			char *s = PyString_AsString(key);
			if (s[0] != '_' || strcmp(s, "__builtins__") != 0) {
				if (Py_VerboseFlag > 1)
135
				    PySys_WriteStderr("#   clear[2] %s\n", s);
136 137 138 139 140 141 142 143 144 145 146
				PyDict_SetItem(d, key, Py_None);
			}
		}
	}

	/* Note: we leave __builtins__ in place, so that destructors
	   of non-global objects defined in this module can still use
	   builtins, in particularly 'None'. */

}

Guido van Rossum's avatar
Guido van Rossum committed
147 148
/* Methods */

149
static int
150
module_init(PyModuleObject *m, PyObject *args, PyObject *kwds)
151
{
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
	static char *kwlist[] = {"name", "doc", NULL};
	PyObject *dict, *name = Py_None, *doc = Py_None;
	if (!PyArg_ParseTupleAndKeywords(args, kwds, "S|O", kwlist,
					 &name, &doc))
		return -1;
	dict = m->md_dict;
	if (dict == NULL) {
		dict = PyDict_New();
		if (dict == NULL)
			return -1;
		m->md_dict = dict;
	}
	if (PyDict_SetItemString(dict, "__name__", name) < 0)
		return -1;
	if (PyDict_SetItemString(dict, "__doc__", doc) < 0)
167 168 169 170
		return -1;
	return 0;
}

Guido van Rossum's avatar
Guido van Rossum committed
171
static void
172
module_dealloc(PyModuleObject *m)
Guido van Rossum's avatar
Guido van Rossum committed
173
{
Neil Schemenauer's avatar
Neil Schemenauer committed
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);
Guido van Rossum's avatar
Guido van Rossum committed
180 181
}

182
static PyObject *
183
module_repr(PyModuleObject *m)
Guido van Rossum's avatar
Guido van Rossum committed
184
{
185 186
	char *name;
	char *filename;
187

188
	name = PyModule_GetName((PyObject *)m);
189
	if (name == NULL) {
190
		PyErr_Clear();
191 192
		name = "?";
	}
193 194 195
	filename = PyModule_GetFilename((PyObject *)m);
	if (filename == NULL) {
		PyErr_Clear();
196
		return PyString_FromFormat("<module '%s' (built-in)>", name);
197
	}
198
	return PyString_FromFormat("<module '%s' from '%s'>", name, filename);
Guido van Rossum's avatar
Guido van Rossum committed
199 200
}

201 202 203 204 205 206 207 208 209 210 211
/* We only need a traverse function, no clear function: If the module
   is in a cycle, md_dict will be cleared as well, which will break
   the cycle. */
static int
module_traverse(PyModuleObject *m, visitproc visit, void *arg)
{
	if (m->md_dict != NULL)
		return visit(m->md_dict, arg);
	return 0;
}

212
PyDoc_STRVAR(module_doc,
213 214 215
"module(name[, doc])\n\
\n\
Create a module object.\n\
216
The name must be a string; the optional doc argument can have any type.");
217

218 219
PyTypeObject PyModule_Type = {
	PyObject_HEAD_INIT(&PyType_Type)
220 221
	0,					/* ob_size */
	"module",				/* tp_name */
Neil Schemenauer's avatar
Neil Schemenauer committed
222
	sizeof(PyModuleObject),			/* tp_size */
223
	0,					/* tp_itemsize */
224
	(destructor)module_dealloc,		/* tp_dealloc */
225
	0,					/* tp_print */
226 227
	0,					/* tp_getattr */
	0,					/* tp_setattr */
228
	0,					/* tp_compare */
229
	(reprfunc)module_repr,			/* tp_repr */
230 231 232 233 234 235
	0,					/* tp_as_number */
	0,					/* tp_as_sequence */
	0,					/* tp_as_mapping */
	0,					/* tp_hash */
	0,					/* tp_call */
	0,					/* tp_str */
236
	PyObject_GenericGetAttr,		/* tp_getattro */
237
	PyObject_GenericSetAttr,		/* tp_setattro */
238
	0,					/* tp_as_buffer */
Neil Schemenauer's avatar
Neil Schemenauer committed
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 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
	0,					/* tp_clear */
	0,					/* tp_richcompare */
	0,					/* tp_weaklistoffset */
	0,					/* tp_iter */
	0,					/* tp_iternext */
	0,					/* tp_methods */
	module_members,				/* tp_members */
	0,					/* tp_getset */
	0,					/* tp_base */
	0,					/* tp_dict */
	0,					/* tp_descr_get */
	0,					/* tp_descr_set */
	offsetof(PyModuleObject, md_dict),	/* tp_dictoffset */
	(initproc)module_init,			/* tp_init */
	PyType_GenericAlloc,			/* tp_alloc */
	PyType_GenericNew,			/* tp_new */
259
	PyObject_GC_Del,		        /* tp_free */
Guido van Rossum's avatar
Guido van Rossum committed
260
};