moduleobject.c 8.09 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
    PyObject_HEAD
    PyObject *md_dict;
10
} PyModuleObject;
Guido van Rossum's avatar
Guido van Rossum committed
11

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

17
PyObject *
18
PyModule_New(const char *name)
Guido van Rossum's avatar
Guido van Rossum committed
19
{
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
    PyModuleObject *m;
    PyObject *nameobj;
    m = PyObject_GC_New(PyModuleObject, &PyModule_Type);
    if (m == NULL)
        return NULL;
    nameobj = PyString_FromString(name);
    m->md_dict = PyDict_New();
    if (m->md_dict == NULL || nameobj == NULL)
        goto fail;
    if (PyDict_SetItemString(m->md_dict, "__name__", nameobj) != 0)
        goto fail;
    if (PyDict_SetItemString(m->md_dict, "__doc__", Py_None) != 0)
        goto fail;
    if (PyDict_SetItemString(m->md_dict, "__package__", Py_None) != 0)
        goto fail;
    Py_DECREF(nameobj);
    PyObject_GC_Track(m);
    return (PyObject *)m;
38 39

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

45
PyObject *
46
PyModule_GetDict(PyObject *m)
Guido van Rossum's avatar
Guido van Rossum committed
47
{
48 49 50 51 52 53 54 55 56
    PyObject *d;
    if (!PyModule_Check(m)) {
        PyErr_BadInternalCall();
        return NULL;
    }
    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
57 58
}

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

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

99
void
100
_PyModule_Clear(PyObject *m)
101
{
102 103 104 105 106 107
    /* 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). */
108

109 110 111
    Py_ssize_t pos;
    PyObject *key, *value;
    PyObject *d;
112

113 114 115
    d = ((PyModuleObject *)m)->md_dict;
    if (d == NULL)
        return;
116

117 118 119 120 121 122 123 124 125 126 127 128
    /* 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)
                    PySys_WriteStderr("#   clear[1] %s\n", s);
                PyDict_SetItem(d, key, Py_None);
            }
        }
    }
129

130 131 132 133 134 135 136 137 138 139 140 141
    /* 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)
                    PySys_WriteStderr("#   clear[2] %s\n", s);
                PyDict_SetItem(d, key, Py_None);
            }
        }
    }
142

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

}

Guido van Rossum's avatar
Guido van Rossum committed
149 150
/* Methods */

151
static int
152
module_init(PyModuleObject *m, PyObject *args, PyObject *kwds)
153
{
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
    static char *kwlist[] = {"name", "doc", NULL};
    PyObject *dict, *name = Py_None, *doc = Py_None;
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "S|O:module.__init__",
                                     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)
        return -1;
    return 0;
171 172
}

Guido van Rossum's avatar
Guido van Rossum committed
173
static void
174
module_dealloc(PyModuleObject *m)
Guido van Rossum's avatar
Guido van Rossum committed
175
{
176 177
    PyObject_GC_UnTrack(m);
    if (m->md_dict != NULL) {
178
        _PyModule_Clear((PyObject *)m);
179 180 181
        Py_DECREF(m->md_dict);
    }
    Py_TYPE(m)->tp_free((PyObject *)m);
Guido van Rossum's avatar
Guido van Rossum committed
182 183
}

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

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

203 204 205 206 207 208
/* 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)
{
209 210
    Py_VISIT(m->md_dict);
    return 0;
211 212
}

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

219
PyTypeObject PyModule_Type = {
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "module",                                   /* tp_name */
    sizeof(PyModuleObject),                     /* tp_size */
    0,                                          /* tp_itemsize */
    (destructor)module_dealloc,                 /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_compare */
    (reprfunc)module_repr,                      /* tp_repr */
    0,                                          /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    PyObject_GenericGetAttr,                    /* tp_getattro */
    PyObject_GenericSetAttr,                    /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        Py_TPFLAGS_BASETYPE,                    /* tp_flags */
    module_doc,                                 /* tp_doc */
    (traverseproc)module_traverse,              /* tp_traverse */
    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 */
    PyObject_GC_Del,                            /* tp_free */
Guido van Rossum's avatar
Guido van Rossum committed
260
};