• 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                 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
module_init(PyModuleObject * m,PyObject * args,PyObject * kwds)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
module_dealloc(PyModuleObject * m)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 *
module_repr(PyModuleObject * m)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
module_traverse(PyModuleObject * m,visitproc visit,void * arg)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