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                 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 
    151 static int
    152 module_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 
    173 static void
    174 module_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 
    184 static PyObject *
    185 module_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. */
    206 static int
    207 module_traverse(PyModuleObject *m, visitproc visit, void *arg)
    208 {
    209     Py_VISIT(m->md_dict);
    210     return 0;
    211 }
    212 
    213 PyDoc_STRVAR(module_doc,
    214 "module(name[, doc])\n\
    215 \n\
    216 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     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 };
    261