• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* Module object implementation */
3 
4 #include "Python.h"
5 #include "internal/pystate.h"
6 #include "structmember.h"
7 
8 static Py_ssize_t max_module_number;
9 
10 typedef struct {
11     PyObject_HEAD
12     PyObject *md_dict;
13     struct PyModuleDef *md_def;
14     void *md_state;
15     PyObject *md_weaklist;
16     PyObject *md_name;  /* for logging purposes after md_dict is cleared */
17 } PyModuleObject;
18 
19 static PyMemberDef module_members[] = {
20     {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
21     {0}
22 };
23 
24 
25 /* Helper for sanity check for traverse not handling m_state == NULL
26  * Issue #32374 */
27 #ifdef Py_DEBUG
28 static int
bad_traverse_test(PyObject * self,void * arg)29 bad_traverse_test(PyObject *self, void *arg) {
30     assert(self != NULL);
31     return 0;
32 }
33 #endif
34 
35 PyTypeObject PyModuleDef_Type = {
36     PyVarObject_HEAD_INIT(&PyType_Type, 0)
37     "moduledef",                                /* tp_name */
38     sizeof(struct PyModuleDef),                 /* tp_basicsize */
39     0,                                          /* tp_itemsize */
40 };
41 
42 
43 PyObject*
PyModuleDef_Init(struct PyModuleDef * def)44 PyModuleDef_Init(struct PyModuleDef* def)
45 {
46     if (PyType_Ready(&PyModuleDef_Type) < 0)
47          return NULL;
48     if (def->m_base.m_index == 0) {
49         max_module_number++;
50         Py_REFCNT(def) = 1;
51         Py_TYPE(def) = &PyModuleDef_Type;
52         def->m_base.m_index = max_module_number;
53     }
54     return (PyObject*)def;
55 }
56 
57 static int
module_init_dict(PyModuleObject * mod,PyObject * md_dict,PyObject * name,PyObject * doc)58 module_init_dict(PyModuleObject *mod, PyObject *md_dict,
59                  PyObject *name, PyObject *doc)
60 {
61     _Py_IDENTIFIER(__name__);
62     _Py_IDENTIFIER(__doc__);
63     _Py_IDENTIFIER(__package__);
64     _Py_IDENTIFIER(__loader__);
65     _Py_IDENTIFIER(__spec__);
66 
67     if (md_dict == NULL)
68         return -1;
69     if (doc == NULL)
70         doc = Py_None;
71 
72     if (_PyDict_SetItemId(md_dict, &PyId___name__, name) != 0)
73         return -1;
74     if (_PyDict_SetItemId(md_dict, &PyId___doc__, doc) != 0)
75         return -1;
76     if (_PyDict_SetItemId(md_dict, &PyId___package__, Py_None) != 0)
77         return -1;
78     if (_PyDict_SetItemId(md_dict, &PyId___loader__, Py_None) != 0)
79         return -1;
80     if (_PyDict_SetItemId(md_dict, &PyId___spec__, Py_None) != 0)
81         return -1;
82     if (PyUnicode_CheckExact(name)) {
83         Py_INCREF(name);
84         Py_XSETREF(mod->md_name, name);
85     }
86 
87     return 0;
88 }
89 
90 
91 PyObject *
PyModule_NewObject(PyObject * name)92 PyModule_NewObject(PyObject *name)
93 {
94     PyModuleObject *m;
95     m = PyObject_GC_New(PyModuleObject, &PyModule_Type);
96     if (m == NULL)
97         return NULL;
98     m->md_def = NULL;
99     m->md_state = NULL;
100     m->md_weaklist = NULL;
101     m->md_name = NULL;
102     m->md_dict = PyDict_New();
103     if (module_init_dict(m, m->md_dict, name, NULL) != 0)
104         goto fail;
105     PyObject_GC_Track(m);
106     return (PyObject *)m;
107 
108  fail:
109     Py_DECREF(m);
110     return NULL;
111 }
112 
113 PyObject *
PyModule_New(const char * name)114 PyModule_New(const char *name)
115 {
116     PyObject *nameobj, *module;
117     nameobj = PyUnicode_FromString(name);
118     if (nameobj == NULL)
119         return NULL;
120     module = PyModule_NewObject(nameobj);
121     Py_DECREF(nameobj);
122     return module;
123 }
124 
125 /* Check API/ABI version
126  * Issues a warning on mismatch, which is usually not fatal.
127  * Returns 0 if an exception is raised.
128  */
129 static int
check_api_version(const char * name,int module_api_version)130 check_api_version(const char *name, int module_api_version)
131 {
132     if (module_api_version != PYTHON_API_VERSION && module_api_version != PYTHON_ABI_VERSION) {
133         int err;
134         err = PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
135             "Python C API version mismatch for module %.100s: "
136             "This Python has API version %d, module %.100s has version %d.",
137              name,
138              PYTHON_API_VERSION, name, module_api_version);
139         if (err)
140             return 0;
141     }
142     return 1;
143 }
144 
145 static int
_add_methods_to_object(PyObject * module,PyObject * name,PyMethodDef * functions)146 _add_methods_to_object(PyObject *module, PyObject *name, PyMethodDef *functions)
147 {
148     PyObject *func;
149     PyMethodDef *fdef;
150 
151     for (fdef = functions; fdef->ml_name != NULL; fdef++) {
152         if ((fdef->ml_flags & METH_CLASS) ||
153             (fdef->ml_flags & METH_STATIC)) {
154             PyErr_SetString(PyExc_ValueError,
155                             "module functions cannot set"
156                             " METH_CLASS or METH_STATIC");
157             return -1;
158         }
159         func = PyCFunction_NewEx(fdef, (PyObject*)module, name);
160         if (func == NULL) {
161             return -1;
162         }
163         if (PyObject_SetAttrString(module, fdef->ml_name, func) != 0) {
164             Py_DECREF(func);
165             return -1;
166         }
167         Py_DECREF(func);
168     }
169 
170     return 0;
171 }
172 
173 PyObject *
PyModule_Create2(struct PyModuleDef * module,int module_api_version)174 PyModule_Create2(struct PyModuleDef* module, int module_api_version)
175 {
176     if (!_PyImport_IsInitialized(PyThreadState_GET()->interp))
177         Py_FatalError("Python import machinery not initialized");
178     return _PyModule_CreateInitialized(module, module_api_version);
179 }
180 
181 PyObject *
_PyModule_CreateInitialized(struct PyModuleDef * module,int module_api_version)182 _PyModule_CreateInitialized(struct PyModuleDef* module, int module_api_version)
183 {
184     const char* name;
185     PyModuleObject *m;
186 
187     if (!PyModuleDef_Init(module))
188         return NULL;
189     name = module->m_name;
190     if (!check_api_version(name, module_api_version)) {
191         return NULL;
192     }
193     if (module->m_slots) {
194         PyErr_Format(
195             PyExc_SystemError,
196             "module %s: PyModule_Create is incompatible with m_slots", name);
197         return NULL;
198     }
199     /* Make sure name is fully qualified.
200 
201        This is a bit of a hack: when the shared library is loaded,
202        the module name is "package.module", but the module calls
203        PyModule_Create*() with just "module" for the name.  The shared
204        library loader squirrels away the true name of the module in
205        _Py_PackageContext, and PyModule_Create*() will substitute this
206        (if the name actually matches).
207     */
208     if (_Py_PackageContext != NULL) {
209         const char *p = strrchr(_Py_PackageContext, '.');
210         if (p != NULL && strcmp(module->m_name, p+1) == 0) {
211             name = _Py_PackageContext;
212             _Py_PackageContext = NULL;
213         }
214     }
215     if ((m = (PyModuleObject*)PyModule_New(name)) == NULL)
216         return NULL;
217 
218     if (module->m_size > 0) {
219         m->md_state = PyMem_MALLOC(module->m_size);
220         if (!m->md_state) {
221             PyErr_NoMemory();
222             Py_DECREF(m);
223             return NULL;
224         }
225         memset(m->md_state, 0, module->m_size);
226     }
227 
228     if (module->m_methods != NULL) {
229         if (PyModule_AddFunctions((PyObject *) m, module->m_methods) != 0) {
230             Py_DECREF(m);
231             return NULL;
232         }
233     }
234     if (module->m_doc != NULL) {
235         if (PyModule_SetDocString((PyObject *) m, module->m_doc) != 0) {
236             Py_DECREF(m);
237             return NULL;
238         }
239     }
240     m->md_def = module;
241     return (PyObject*)m;
242 }
243 
244 PyObject *
PyModule_FromDefAndSpec2(struct PyModuleDef * def,PyObject * spec,int module_api_version)245 PyModule_FromDefAndSpec2(struct PyModuleDef* def, PyObject *spec, int module_api_version)
246 {
247     PyModuleDef_Slot* cur_slot;
248     PyObject *(*create)(PyObject *, PyModuleDef*) = NULL;
249     PyObject *nameobj;
250     PyObject *m = NULL;
251     int has_execution_slots = 0;
252     const char *name;
253     int ret;
254 
255     PyModuleDef_Init(def);
256 
257     nameobj = PyObject_GetAttrString(spec, "name");
258     if (nameobj == NULL) {
259         return NULL;
260     }
261     name = PyUnicode_AsUTF8(nameobj);
262     if (name == NULL) {
263         goto error;
264     }
265 
266     if (!check_api_version(name, module_api_version)) {
267         goto error;
268     }
269 
270     if (def->m_size < 0) {
271         PyErr_Format(
272             PyExc_SystemError,
273             "module %s: m_size may not be negative for multi-phase initialization",
274             name);
275         goto error;
276     }
277 
278     for (cur_slot = def->m_slots; cur_slot && cur_slot->slot; cur_slot++) {
279         if (cur_slot->slot == Py_mod_create) {
280             if (create) {
281                 PyErr_Format(
282                     PyExc_SystemError,
283                     "module %s has multiple create slots",
284                     name);
285                 goto error;
286             }
287             create = cur_slot->value;
288         } else if (cur_slot->slot < 0 || cur_slot->slot > _Py_mod_LAST_SLOT) {
289             PyErr_Format(
290                 PyExc_SystemError,
291                 "module %s uses unknown slot ID %i",
292                 name, cur_slot->slot);
293             goto error;
294         } else {
295             has_execution_slots = 1;
296         }
297     }
298 
299     if (create) {
300         m = create(spec, def);
301         if (m == NULL) {
302             if (!PyErr_Occurred()) {
303                 PyErr_Format(
304                     PyExc_SystemError,
305                     "creation of module %s failed without setting an exception",
306                     name);
307             }
308             goto error;
309         } else {
310             if (PyErr_Occurred()) {
311                 PyErr_Format(PyExc_SystemError,
312                             "creation of module %s raised unreported exception",
313                             name);
314                 goto error;
315             }
316         }
317     } else {
318         m = PyModule_NewObject(nameobj);
319         if (m == NULL) {
320             goto error;
321         }
322     }
323 
324     if (PyModule_Check(m)) {
325         ((PyModuleObject*)m)->md_state = NULL;
326         ((PyModuleObject*)m)->md_def = def;
327     } else {
328         if (def->m_size > 0 || def->m_traverse || def->m_clear || def->m_free) {
329             PyErr_Format(
330                 PyExc_SystemError,
331                 "module %s is not a module object, but requests module state",
332                 name);
333             goto error;
334         }
335         if (has_execution_slots) {
336             PyErr_Format(
337                 PyExc_SystemError,
338                 "module %s specifies execution slots, but did not create "
339                     "a ModuleType instance",
340                 name);
341             goto error;
342         }
343     }
344 
345     if (def->m_methods != NULL) {
346         ret = _add_methods_to_object(m, nameobj, def->m_methods);
347         if (ret != 0) {
348             goto error;
349         }
350     }
351 
352     if (def->m_doc != NULL) {
353         ret = PyModule_SetDocString(m, def->m_doc);
354         if (ret != 0) {
355             goto error;
356         }
357     }
358 
359     /* Sanity check for traverse not handling m_state == NULL
360      * This doesn't catch all possible cases, but in many cases it should
361      * make many cases of invalid code crash or raise Valgrind issues
362      * sooner than they would otherwise.
363      * Issue #32374 */
364 #ifdef Py_DEBUG
365     if (def->m_traverse != NULL) {
366         def->m_traverse(m, bad_traverse_test, NULL);
367     }
368 #endif
369     Py_DECREF(nameobj);
370     return m;
371 
372 error:
373     Py_DECREF(nameobj);
374     Py_XDECREF(m);
375     return NULL;
376 }
377 
378 int
PyModule_ExecDef(PyObject * module,PyModuleDef * def)379 PyModule_ExecDef(PyObject *module, PyModuleDef *def)
380 {
381     PyModuleDef_Slot *cur_slot;
382     const char *name;
383     int ret;
384 
385     name = PyModule_GetName(module);
386     if (name == NULL) {
387         return -1;
388     }
389 
390     if (def->m_size >= 0) {
391         PyModuleObject *md = (PyModuleObject*)module;
392         if (md->md_state == NULL) {
393             /* Always set a state pointer; this serves as a marker to skip
394              * multiple initialization (importlib.reload() is no-op) */
395             md->md_state = PyMem_MALLOC(def->m_size);
396             if (!md->md_state) {
397                 PyErr_NoMemory();
398                 return -1;
399             }
400             memset(md->md_state, 0, def->m_size);
401         }
402     }
403 
404     if (def->m_slots == NULL) {
405         return 0;
406     }
407 
408     for (cur_slot = def->m_slots; cur_slot && cur_slot->slot; cur_slot++) {
409         switch (cur_slot->slot) {
410             case Py_mod_create:
411                 /* handled in PyModule_FromDefAndSpec2 */
412                 break;
413             case Py_mod_exec:
414                 ret = ((int (*)(PyObject *))cur_slot->value)(module);
415                 if (ret != 0) {
416                     if (!PyErr_Occurred()) {
417                         PyErr_Format(
418                             PyExc_SystemError,
419                             "execution of module %s failed without setting an exception",
420                             name);
421                     }
422                     return -1;
423                 }
424                 if (PyErr_Occurred()) {
425                     PyErr_Format(
426                         PyExc_SystemError,
427                         "execution of module %s raised unreported exception",
428                         name);
429                     return -1;
430                 }
431                 break;
432             default:
433                 PyErr_Format(
434                     PyExc_SystemError,
435                     "module %s initialized with unknown slot %i",
436                     name, cur_slot->slot);
437                 return -1;
438         }
439     }
440     return 0;
441 }
442 
443 int
PyModule_AddFunctions(PyObject * m,PyMethodDef * functions)444 PyModule_AddFunctions(PyObject *m, PyMethodDef *functions)
445 {
446     int res;
447     PyObject *name = PyModule_GetNameObject(m);
448     if (name == NULL) {
449         return -1;
450     }
451 
452     res = _add_methods_to_object(m, name, functions);
453     Py_DECREF(name);
454     return res;
455 }
456 
457 int
PyModule_SetDocString(PyObject * m,const char * doc)458 PyModule_SetDocString(PyObject *m, const char *doc)
459 {
460     PyObject *v;
461     _Py_IDENTIFIER(__doc__);
462 
463     v = PyUnicode_FromString(doc);
464     if (v == NULL || _PyObject_SetAttrId(m, &PyId___doc__, v) != 0) {
465         Py_XDECREF(v);
466         return -1;
467     }
468     Py_DECREF(v);
469     return 0;
470 }
471 
472 PyObject *
PyModule_GetDict(PyObject * m)473 PyModule_GetDict(PyObject *m)
474 {
475     PyObject *d;
476     if (!PyModule_Check(m)) {
477         PyErr_BadInternalCall();
478         return NULL;
479     }
480     d = ((PyModuleObject *)m) -> md_dict;
481     assert(d != NULL);
482     return d;
483 }
484 
485 PyObject*
PyModule_GetNameObject(PyObject * m)486 PyModule_GetNameObject(PyObject *m)
487 {
488     _Py_IDENTIFIER(__name__);
489     PyObject *d;
490     PyObject *name;
491     if (!PyModule_Check(m)) {
492         PyErr_BadArgument();
493         return NULL;
494     }
495     d = ((PyModuleObject *)m)->md_dict;
496     if (d == NULL ||
497         (name = _PyDict_GetItemId(d, &PyId___name__)) == NULL ||
498         !PyUnicode_Check(name))
499     {
500         PyErr_SetString(PyExc_SystemError, "nameless module");
501         return NULL;
502     }
503     Py_INCREF(name);
504     return name;
505 }
506 
507 const char *
PyModule_GetName(PyObject * m)508 PyModule_GetName(PyObject *m)
509 {
510     PyObject *name = PyModule_GetNameObject(m);
511     if (name == NULL)
512         return NULL;
513     Py_DECREF(name);   /* module dict has still a reference */
514     return PyUnicode_AsUTF8(name);
515 }
516 
517 PyObject*
PyModule_GetFilenameObject(PyObject * m)518 PyModule_GetFilenameObject(PyObject *m)
519 {
520     _Py_IDENTIFIER(__file__);
521     PyObject *d;
522     PyObject *fileobj;
523     if (!PyModule_Check(m)) {
524         PyErr_BadArgument();
525         return NULL;
526     }
527     d = ((PyModuleObject *)m)->md_dict;
528     if (d == NULL ||
529         (fileobj = _PyDict_GetItemId(d, &PyId___file__)) == NULL ||
530         !PyUnicode_Check(fileobj))
531     {
532         PyErr_SetString(PyExc_SystemError, "module filename missing");
533         return NULL;
534     }
535     Py_INCREF(fileobj);
536     return fileobj;
537 }
538 
539 const char *
PyModule_GetFilename(PyObject * m)540 PyModule_GetFilename(PyObject *m)
541 {
542     PyObject *fileobj;
543     const char *utf8;
544     fileobj = PyModule_GetFilenameObject(m);
545     if (fileobj == NULL)
546         return NULL;
547     utf8 = PyUnicode_AsUTF8(fileobj);
548     Py_DECREF(fileobj);   /* module dict has still a reference */
549     return utf8;
550 }
551 
552 PyModuleDef*
PyModule_GetDef(PyObject * m)553 PyModule_GetDef(PyObject* m)
554 {
555     if (!PyModule_Check(m)) {
556         PyErr_BadArgument();
557         return NULL;
558     }
559     return ((PyModuleObject *)m)->md_def;
560 }
561 
562 void*
PyModule_GetState(PyObject * m)563 PyModule_GetState(PyObject* m)
564 {
565     if (!PyModule_Check(m)) {
566         PyErr_BadArgument();
567         return NULL;
568     }
569     return ((PyModuleObject *)m)->md_state;
570 }
571 
572 void
_PyModule_Clear(PyObject * m)573 _PyModule_Clear(PyObject *m)
574 {
575     PyObject *d = ((PyModuleObject *)m)->md_dict;
576     if (d != NULL)
577         _PyModule_ClearDict(d);
578 }
579 
580 void
_PyModule_ClearDict(PyObject * d)581 _PyModule_ClearDict(PyObject *d)
582 {
583     /* To make the execution order of destructors for global
584        objects a bit more predictable, we first zap all objects
585        whose name starts with a single underscore, before we clear
586        the entire dictionary.  We zap them by replacing them with
587        None, rather than deleting them from the dictionary, to
588        avoid rehashing the dictionary (to some extent). */
589 
590     Py_ssize_t pos;
591     PyObject *key, *value;
592 
593     /* First, clear only names starting with a single underscore */
594     pos = 0;
595     while (PyDict_Next(d, &pos, &key, &value)) {
596         if (value != Py_None && PyUnicode_Check(key)) {
597             if (PyUnicode_READ_CHAR(key, 0) == '_' &&
598                 PyUnicode_READ_CHAR(key, 1) != '_') {
599                 if (Py_VerboseFlag > 1) {
600                     const char *s = PyUnicode_AsUTF8(key);
601                     if (s != NULL)
602                         PySys_WriteStderr("#   clear[1] %s\n", s);
603                     else
604                         PyErr_Clear();
605                 }
606                 if (PyDict_SetItem(d, key, Py_None) != 0)
607                     PyErr_Clear();
608             }
609         }
610     }
611 
612     /* Next, clear all names except for __builtins__ */
613     pos = 0;
614     while (PyDict_Next(d, &pos, &key, &value)) {
615         if (value != Py_None && PyUnicode_Check(key)) {
616             if (PyUnicode_READ_CHAR(key, 0) != '_' ||
617                 !_PyUnicode_EqualToASCIIString(key, "__builtins__"))
618             {
619                 if (Py_VerboseFlag > 1) {
620                     const char *s = PyUnicode_AsUTF8(key);
621                     if (s != NULL)
622                         PySys_WriteStderr("#   clear[2] %s\n", s);
623                     else
624                         PyErr_Clear();
625                 }
626                 if (PyDict_SetItem(d, key, Py_None) != 0)
627                     PyErr_Clear();
628             }
629         }
630     }
631 
632     /* Note: we leave __builtins__ in place, so that destructors
633        of non-global objects defined in this module can still use
634        builtins, in particularly 'None'. */
635 
636 }
637 
638 /*[clinic input]
639 class module "PyModuleObject *" "&PyModule_Type"
640 [clinic start generated code]*/
641 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=3e35d4f708ecb6af]*/
642 
643 #include "clinic/moduleobject.c.h"
644 
645 /* Methods */
646 
647 /*[clinic input]
648 module.__init__
649     name: unicode
650     doc: object = None
651 
652 Create a module object.
653 
654 The name must be a string; the optional doc argument can have any type.
655 [clinic start generated code]*/
656 
657 static int
module___init___impl(PyModuleObject * self,PyObject * name,PyObject * doc)658 module___init___impl(PyModuleObject *self, PyObject *name, PyObject *doc)
659 /*[clinic end generated code: output=e7e721c26ce7aad7 input=57f9e177401e5e1e]*/
660 {
661     PyObject *dict = self->md_dict;
662     if (dict == NULL) {
663         dict = PyDict_New();
664         if (dict == NULL)
665             return -1;
666         self->md_dict = dict;
667     }
668     if (module_init_dict(self, dict, name, doc) < 0)
669         return -1;
670     return 0;
671 }
672 
673 static void
module_dealloc(PyModuleObject * m)674 module_dealloc(PyModuleObject *m)
675 {
676     PyObject_GC_UnTrack(m);
677     if (Py_VerboseFlag && m->md_name) {
678         PySys_FormatStderr("# destroy %S\n", m->md_name);
679     }
680     if (m->md_weaklist != NULL)
681         PyObject_ClearWeakRefs((PyObject *) m);
682     if (m->md_def && m->md_def->m_free)
683         m->md_def->m_free(m);
684     Py_XDECREF(m->md_dict);
685     Py_XDECREF(m->md_name);
686     if (m->md_state != NULL)
687         PyMem_FREE(m->md_state);
688     Py_TYPE(m)->tp_free((PyObject *)m);
689 }
690 
691 static PyObject *
module_repr(PyModuleObject * m)692 module_repr(PyModuleObject *m)
693 {
694     PyThreadState *tstate = PyThreadState_GET();
695     PyInterpreterState *interp = tstate->interp;
696 
697     return PyObject_CallMethod(interp->importlib, "_module_repr", "O", m);
698 }
699 
700 static PyObject*
module_getattro(PyModuleObject * m,PyObject * name)701 module_getattro(PyModuleObject *m, PyObject *name)
702 {
703     PyObject *attr, *mod_name, *getattr;
704     attr = PyObject_GenericGetAttr((PyObject *)m, name);
705     if (attr || !PyErr_ExceptionMatches(PyExc_AttributeError)) {
706         return attr;
707     }
708     PyErr_Clear();
709     if (m->md_dict) {
710         _Py_IDENTIFIER(__getattr__);
711         getattr = _PyDict_GetItemId(m->md_dict, &PyId___getattr__);
712         if (getattr) {
713             PyObject* stack[1] = {name};
714             return _PyObject_FastCall(getattr, stack, 1);
715         }
716         _Py_IDENTIFIER(__name__);
717         mod_name = _PyDict_GetItemId(m->md_dict, &PyId___name__);
718         if (mod_name && PyUnicode_Check(mod_name)) {
719             PyErr_Format(PyExc_AttributeError,
720                         "module '%U' has no attribute '%U'", mod_name, name);
721             return NULL;
722         }
723     }
724     PyErr_Format(PyExc_AttributeError,
725                 "module has no attribute '%U'", name);
726     return NULL;
727 }
728 
729 static int
module_traverse(PyModuleObject * m,visitproc visit,void * arg)730 module_traverse(PyModuleObject *m, visitproc visit, void *arg)
731 {
732     if (m->md_def && m->md_def->m_traverse) {
733         int res = m->md_def->m_traverse((PyObject*)m, visit, arg);
734         if (res)
735             return res;
736     }
737     Py_VISIT(m->md_dict);
738     return 0;
739 }
740 
741 static int
module_clear(PyModuleObject * m)742 module_clear(PyModuleObject *m)
743 {
744     if (m->md_def && m->md_def->m_clear) {
745         int res = m->md_def->m_clear((PyObject*)m);
746         if (res)
747             return res;
748     }
749     Py_CLEAR(m->md_dict);
750     return 0;
751 }
752 
753 static PyObject *
module_dir(PyObject * self,PyObject * args)754 module_dir(PyObject *self, PyObject *args)
755 {
756     _Py_IDENTIFIER(__dict__);
757     PyObject *result = NULL;
758     PyObject *dict = _PyObject_GetAttrId(self, &PyId___dict__);
759 
760     if (dict != NULL) {
761         if (PyDict_Check(dict)) {
762             PyObject *dirfunc = PyDict_GetItemString(dict, "__dir__");
763             if (dirfunc) {
764                 result = _PyObject_CallNoArg(dirfunc);
765             }
766             else {
767                 result = PyDict_Keys(dict);
768             }
769         }
770         else {
771             const char *name = PyModule_GetName(self);
772             if (name)
773                 PyErr_Format(PyExc_TypeError,
774                              "%.200s.__dict__ is not a dictionary",
775                              name);
776         }
777     }
778 
779     Py_XDECREF(dict);
780     return result;
781 }
782 
783 static PyMethodDef module_methods[] = {
784     {"__dir__", module_dir, METH_NOARGS,
785      PyDoc_STR("__dir__() -> list\nspecialized dir() implementation")},
786     {0}
787 };
788 
789 PyTypeObject PyModule_Type = {
790     PyVarObject_HEAD_INIT(&PyType_Type, 0)
791     "module",                                   /* tp_name */
792     sizeof(PyModuleObject),                     /* tp_basicsize */
793     0,                                          /* tp_itemsize */
794     (destructor)module_dealloc,                 /* tp_dealloc */
795     0,                                          /* tp_print */
796     0,                                          /* tp_getattr */
797     0,                                          /* tp_setattr */
798     0,                                          /* tp_reserved */
799     (reprfunc)module_repr,                      /* tp_repr */
800     0,                                          /* tp_as_number */
801     0,                                          /* tp_as_sequence */
802     0,                                          /* tp_as_mapping */
803     0,                                          /* tp_hash */
804     0,                                          /* tp_call */
805     0,                                          /* tp_str */
806     (getattrofunc)module_getattro,              /* tp_getattro */
807     PyObject_GenericSetAttr,                    /* tp_setattro */
808     0,                                          /* tp_as_buffer */
809     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
810         Py_TPFLAGS_BASETYPE,                    /* tp_flags */
811     module___init____doc__,                     /* tp_doc */
812     (traverseproc)module_traverse,              /* tp_traverse */
813     (inquiry)module_clear,                      /* tp_clear */
814     0,                                          /* tp_richcompare */
815     offsetof(PyModuleObject, md_weaklist),      /* tp_weaklistoffset */
816     0,                                          /* tp_iter */
817     0,                                          /* tp_iternext */
818     module_methods,                             /* tp_methods */
819     module_members,                             /* tp_members */
820     0,                                          /* tp_getset */
821     0,                                          /* tp_base */
822     0,                                          /* tp_dict */
823     0,                                          /* tp_descr_get */
824     0,                                          /* tp_descr_set */
825     offsetof(PyModuleObject, md_dict),          /* tp_dictoffset */
826     module___init__,                            /* tp_init */
827     PyType_GenericAlloc,                        /* tp_alloc */
828     PyType_GenericNew,                          /* tp_new */
829     PyObject_GC_Del,                            /* tp_free */
830 };
831