Coverage Report

Created: 2025-07-11 06:59

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