153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* Module object implementation */
353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#include "Python.h"
553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#include "structmember.h"
653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieltypedef struct {
853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject_HEAD
953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *md_dict;
1053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel} PyModuleObject;
1153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
1253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyMemberDef module_members[] = {
1353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
1453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    {0}
1553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel};
1653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
1753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielPyObject *
1853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielPyModule_New(const char *name)
1953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
2053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyModuleObject *m;
2153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *nameobj;
2253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    m = PyObject_GC_New(PyModuleObject, &PyModule_Type);
2353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (m == NULL)
2453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
2553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    nameobj = PyString_FromString(name);
2653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    m->md_dict = PyDict_New();
2753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (m->md_dict == NULL || nameobj == NULL)
2853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        goto fail;
2953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (PyDict_SetItemString(m->md_dict, "__name__", nameobj) != 0)
3053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        goto fail;
3153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (PyDict_SetItemString(m->md_dict, "__doc__", Py_None) != 0)
3253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        goto fail;
3353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (PyDict_SetItemString(m->md_dict, "__package__", Py_None) != 0)
3453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        goto fail;
3553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_DECREF(nameobj);
3653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject_GC_Track(m);
3753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return (PyObject *)m;
3853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
3953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel fail:
4053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_XDECREF(nameobj);
4153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_DECREF(m);
4253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return NULL;
4353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
4453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
4553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielPyObject *
4653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielPyModule_GetDict(PyObject *m)
4753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
4853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *d;
4953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (!PyModule_Check(m)) {
5053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyErr_BadInternalCall();
5153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
5253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
5353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    d = ((PyModuleObject *)m) -> md_dict;
5453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (d == NULL)
5553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        ((PyModuleObject *)m) -> md_dict = d = PyDict_New();
5653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return d;
5753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
5853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
5953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielchar *
6053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielPyModule_GetName(PyObject *m)
6153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
6253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *d;
6353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *nameobj;
6453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (!PyModule_Check(m)) {
6553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyErr_BadArgument();
6653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
6753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
6853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    d = ((PyModuleObject *)m)->md_dict;
6953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (d == NULL ||
7053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        (nameobj = PyDict_GetItemString(d, "__name__")) == NULL ||
7153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        !PyString_Check(nameobj))
7253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    {
7353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyErr_SetString(PyExc_SystemError, "nameless module");
7453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
7553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
7653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return PyString_AsString(nameobj);
7753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
7853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
7953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielchar *
8053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielPyModule_GetFilename(PyObject *m)
8153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
8253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *d;
8353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *fileobj;
8453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (!PyModule_Check(m)) {
8553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyErr_BadArgument();
8653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
8753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
8853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    d = ((PyModuleObject *)m)->md_dict;
8953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (d == NULL ||
9053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        (fileobj = PyDict_GetItemString(d, "__file__")) == NULL ||
9153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        !PyString_Check(fileobj))
9253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    {
9353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyErr_SetString(PyExc_SystemError, "module filename missing");
9453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
9553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
9653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return PyString_AsString(fileobj);
9753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
9853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
9953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielvoid
10053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel_PyModule_Clear(PyObject *m)
10153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
10253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* To make the execution order of destructors for global
10353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       objects a bit more predictable, we first zap all objects
10453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       whose name starts with a single underscore, before we clear
10553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       the entire dictionary.  We zap them by replacing them with
10653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       None, rather than deleting them from the dictionary, to
10753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       avoid rehashing the dictionary (to some extent). */
10853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
10953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_ssize_t pos;
11053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *key, *value;
11153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *d;
11253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
11353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    d = ((PyModuleObject *)m)->md_dict;
11453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (d == NULL)
11553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return;
11653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
11753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* First, clear only names starting with a single underscore */
11853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    pos = 0;
11953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    while (PyDict_Next(d, &pos, &key, &value)) {
12053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (value != Py_None && PyString_Check(key)) {
12153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            char *s = PyString_AsString(key);
12253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            if (s[0] == '_' && s[1] != '_') {
12353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                if (Py_VerboseFlag > 1)
12453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                    PySys_WriteStderr("#   clear[1] %s\n", s);
12553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                if (PyDict_SetItem(d, key, Py_None) != 0)
12653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                    PyErr_Clear();
12753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            }
12853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        }
12953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
13053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
13153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* Next, clear all names except for __builtins__ */
13253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    pos = 0;
13353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    while (PyDict_Next(d, &pos, &key, &value)) {
13453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (value != Py_None && PyString_Check(key)) {
13553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            char *s = PyString_AsString(key);
13653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            if (s[0] != '_' || strcmp(s, "__builtins__") != 0) {
13753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                if (Py_VerboseFlag > 1)
13853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                    PySys_WriteStderr("#   clear[2] %s\n", s);
13953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                if (PyDict_SetItem(d, key, Py_None) != 0)
14053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                    PyErr_Clear();
14153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            }
14253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        }
14353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
14453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
14553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* Note: we leave __builtins__ in place, so that destructors
14653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       of non-global objects defined in this module can still use
14753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       builtins, in particularly 'None'. */
14853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
14953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
15053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
15153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* Methods */
15253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
15353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
15453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielmodule_init(PyModuleObject *m, PyObject *args, PyObject *kwds)
15553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
15653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    static char *kwlist[] = {"name", "doc", NULL};
15753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *dict, *name = Py_None, *doc = Py_None;
15853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (!PyArg_ParseTupleAndKeywords(args, kwds, "S|O:module.__init__",
15953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                                     kwlist, &name, &doc))
16053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return -1;
16153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    dict = m->md_dict;
16253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (dict == NULL) {
16353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        dict = PyDict_New();
16453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (dict == NULL)
16553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            return -1;
16653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        m->md_dict = dict;
16753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
16853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (PyDict_SetItemString(dict, "__name__", name) < 0)
16953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return -1;
17053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (PyDict_SetItemString(dict, "__doc__", doc) < 0)
17153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return -1;
17253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return 0;
17353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
17453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
17553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic void
17653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielmodule_dealloc(PyModuleObject *m)
17753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
17853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject_GC_UnTrack(m);
17953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (m->md_dict != NULL) {
18053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        _PyModule_Clear((PyObject *)m);
18153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_DECREF(m->md_dict);
18253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
18353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_TYPE(m)->tp_free((PyObject *)m);
18453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
18553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
18653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyObject *
18753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielmodule_repr(PyModuleObject *m)
18853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
18953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    char *name;
19053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    char *filename;
19153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
19253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    name = PyModule_GetName((PyObject *)m);
19353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (name == NULL) {
19453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyErr_Clear();
19553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        name = "?";
19653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
19753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    filename = PyModule_GetFilename((PyObject *)m);
19853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (filename == NULL) {
19953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyErr_Clear();
20053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return PyString_FromFormat("<module '%s' (built-in)>", name);
20153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
20253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return PyString_FromFormat("<module '%s' from '%s'>", name, filename);
20353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
20453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
20553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* We only need a traverse function, no clear function: If the module
20653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   is in a cycle, md_dict will be cleared as well, which will break
20753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   the cycle. */
20853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
20953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielmodule_traverse(PyModuleObject *m, visitproc visit, void *arg)
21053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
21153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_VISIT(m->md_dict);
21253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return 0;
21353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
21453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
21553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielPyDoc_STRVAR(module_doc,
21653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel"module(name[, doc])\n\
21753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel\n\
21853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielCreate a module object.\n\
21953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielThe name must be a string; the optional doc argument can have any type.");
22053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
22153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielPyTypeObject PyModule_Type = {
22253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyVarObject_HEAD_INIT(&PyType_Type, 0)
22353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    "module",                                   /* tp_name */
22453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    sizeof(PyModuleObject),                     /* tp_size */
22553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_itemsize */
22653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    (destructor)module_dealloc,                 /* tp_dealloc */
22753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_print */
22853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_getattr */
22953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_setattr */
23053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_compare */
23153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    (reprfunc)module_repr,                      /* tp_repr */
23253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_as_number */
23353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_as_sequence */
23453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_as_mapping */
23553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_hash */
23653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_call */
23753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_str */
23853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject_GenericGetAttr,                    /* tp_getattro */
23953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject_GenericSetAttr,                    /* tp_setattro */
24053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_as_buffer */
24153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
24253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_TPFLAGS_BASETYPE,                    /* tp_flags */
24353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    module_doc,                                 /* tp_doc */
24453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    (traverseproc)module_traverse,              /* tp_traverse */
24553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_clear */
24653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_richcompare */
24753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_weaklistoffset */
24853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_iter */
24953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_iternext */
25053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_methods */
25153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    module_members,                             /* tp_members */
25253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_getset */
25353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_base */
25453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_dict */
25553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_descr_get */
25653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                          /* tp_descr_set */
25753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    offsetof(PyModuleObject, md_dict),          /* tp_dictoffset */
25853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    (initproc)module_init,                      /* tp_init */
25953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyType_GenericAlloc,                        /* tp_alloc */
26053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyType_GenericNew,                          /* tp_new */
26153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject_GC_Del,                            /* tp_free */
26253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel};
263