Home | History | Annotate | Download | only in Objects
      1 
      2 /* Module object implementation */
      3 
      4 #include "Python.h"
      5 #include "structmember.h"
      6 
      7 typedef struct {
      8     PyObject_HEAD
      9     PyObject *md_dict;
     10 } PyModuleObject;
     11 
     12 static PyMemberDef module_members[] = {
     13     {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
     14     {0}
     15 };
     16 
     17 PyObject *
     18 PyModule_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 
     45 PyObject *
     46 PyModule_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 
     59 char *
     60 PyModule_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 
     79 char *
     80 PyModule_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 
     99 void
    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                 if (PyDict_SetItem(d, key, Py_None) != 0)
    126                     PyErr_Clear();
    127             }
    128         }
    129     }
    130 
    131     /* Next, clear all names except for __builtins__ */
    132     pos = 0;
    133     while (PyDict_Next(d, &pos, &key, &value)) {
    134         if (value != Py_None && PyString_Check(key)) {
    135             char *s = PyString_AsString(key);
    136             if (s[0] != '_' || strcmp(s, "__builtins__") != 0) {
    137                 if (Py_VerboseFlag > 1)
    138                     PySys_WriteStderr("#   clear[2] %s\n", s);
    139                 if (PyDict_SetItem(d, key, Py_None) != 0)
    140                     PyErr_Clear();
    141             }
    142         }
    143     }
    144 
    145     /* Note: we leave __builtins__ in place, so that destructors
    146        of non-global objects defined in this module can still use
    147        builtins, in particularly 'None'. */
    148 
    149 }
    150 
    151 /* Methods */
    152 
    153 static int
    154 module_init(PyModuleObject *m, PyObject *args, PyObject *kwds)
    155 {
    156     static char *kwlist[] = {"name", "doc", NULL};
    157     PyObject *dict, *name = Py_None, *doc = Py_None;
    158     if (!PyArg_ParseTupleAndKeywords(args, kwds, "S|O:module.__init__",
    159                                      kwlist, &name, &doc))
    160         return -1;
    161     dict = m->md_dict;
    162     if (dict == NULL) {
    163         dict = PyDict_New();
    164         if (dict == NULL)
    165             return -1;
    166         m->md_dict = dict;
    167     }
    168     if (PyDict_SetItemString(dict, "__name__", name) < 0)
    169         return -1;
    170     if (PyDict_SetItemString(dict, "__doc__", doc) < 0)
    171         return -1;
    172     return 0;
    173 }
    174 
    175 static void
    176 module_dealloc(PyModuleObject *m)
    177 {
    178     PyObject_GC_UnTrack(m);
    179     if (m->md_dict != NULL) {
    180         _PyModule_Clear((PyObject *)m);
    181         Py_DECREF(m->md_dict);
    182     }
    183     Py_TYPE(m)->tp_free((PyObject *)m);
    184 }
    185 
    186 static PyObject *
    187 module_repr(PyModuleObject *m)
    188 {
    189     char *name;
    190     char *filename;
    191 
    192     name = PyModule_GetName((PyObject *)m);
    193     if (name == NULL) {
    194         PyErr_Clear();
    195         name = "?";
    196     }
    197     filename = PyModule_GetFilename((PyObject *)m);
    198     if (filename == NULL) {
    199         PyErr_Clear();
    200         return PyString_FromFormat("<module '%s' (built-in)>", name);
    201     }
    202     return PyString_FromFormat("<module '%s' from '%s'>", name, filename);
    203 }
    204 
    205 /* We only need a traverse function, no clear function: If the module
    206    is in a cycle, md_dict will be cleared as well, which will break
    207    the cycle. */
    208 static int
    209 module_traverse(PyModuleObject *m, visitproc visit, void *arg)
    210 {
    211     Py_VISIT(m->md_dict);
    212     return 0;
    213 }
    214 
    215 PyDoc_STRVAR(module_doc,
    216 "module(name[, doc])\n\
    217 \n\
    218 Create a module object.\n\
    219 The name must be a string; the optional doc argument can have any type.");
    220 
    221 PyTypeObject PyModule_Type = {
    222     PyVarObject_HEAD_INIT(&PyType_Type, 0)
    223     "module",                                   /* tp_name */
    224     sizeof(PyModuleObject),                     /* tp_size */
    225     0,                                          /* tp_itemsize */
    226     (destructor)module_dealloc,                 /* tp_dealloc */
    227     0,                                          /* tp_print */
    228     0,                                          /* tp_getattr */
    229     0,                                          /* tp_setattr */
    230     0,                                          /* tp_compare */
    231     (reprfunc)module_repr,                      /* tp_repr */
    232     0,                                          /* tp_as_number */
    233     0,                                          /* tp_as_sequence */
    234     0,                                          /* tp_as_mapping */
    235     0,                                          /* tp_hash */
    236     0,                                          /* tp_call */
    237     0,                                          /* tp_str */
    238     PyObject_GenericGetAttr,                    /* tp_getattro */
    239     PyObject_GenericSetAttr,                    /* tp_setattro */
    240     0,                                          /* tp_as_buffer */
    241     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
    242         Py_TPFLAGS_BASETYPE,                    /* tp_flags */
    243     module_doc,                                 /* tp_doc */
    244     (traverseproc)module_traverse,              /* tp_traverse */
    245     0,                                          /* tp_clear */
    246     0,                                          /* tp_richcompare */
    247     0,                                          /* tp_weaklistoffset */
    248     0,                                          /* tp_iter */
    249     0,                                          /* tp_iternext */
    250     0,                                          /* tp_methods */
    251     module_members,                             /* tp_members */
    252     0,                                          /* tp_getset */
    253     0,                                          /* tp_base */
    254     0,                                          /* tp_dict */
    255     0,                                          /* tp_descr_get */
    256     0,                                          /* tp_descr_set */
    257     offsetof(PyModuleObject, md_dict),          /* tp_dictoffset */
    258     (initproc)module_init,                      /* tp_init */
    259     PyType_GenericAlloc,                        /* tp_alloc */
    260     PyType_GenericNew,                          /* tp_new */
    261     PyObject_GC_Del,                            /* tp_free */
    262 };
    263