• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *
PyModule_New(const char * name)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 *
PyModule_GetDict(PyObject * m)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 *
PyModule_GetName(PyObject * m)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 *
PyModule_GetFilename(PyObject * m)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
_PyModule_Clear(PyObject * m)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
module_init(PyModuleObject * m,PyObject * args,PyObject * kwds)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
module_dealloc(PyModuleObject * m)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 *
module_repr(PyModuleObject * m)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
module_traverse(PyModuleObject * m,visitproc visit,void * arg)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