Coverage Report

Created: 2026-08-13 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython3/Modules/symtablemodule.c
Line
Count
Source
1
#include "Python.h"
2
#include "pycore_ast.h"           // PyAST_Check()
3
#include "pycore_pyarena.h"       // _PyArena_New()
4
#include "pycore_pythonrun.h"     // _Py_SourceAsString()
5
#include "pycore_symtable.h"      // struct symtable
6
7
#include "clinic/symtablemodule.c.h"
8
/*[clinic input]
9
module _symtable
10
[clinic start generated code]*/
11
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f4685845a7100605]*/
12
13
14
static struct symtable *
15
symtable_from_ast(PyObject *source, PyObject *filename, int compile_mode)
16
0
{
17
0
    PyArena *arena = _PyArena_New();
18
0
    if (arena == NULL) {
19
0
        return NULL;
20
0
    }
21
0
    struct symtable *st = NULL;
22
0
    mod_ty mod = PyAST_obj2mod(source, arena, compile_mode);
23
0
    if (mod == NULL || !_PyAST_Validate(mod)) {
24
0
        goto finally;
25
0
    }
26
0
    _PyFutureFeatures future;
27
0
    if (!_PyFuture_FromAST(mod, filename, &future)) {
28
0
        goto finally;
29
0
    }
30
0
    st = _PySymtable_Build(mod, filename, &future);
31
0
finally:
32
0
    _PyArena_Free(arena);
33
0
    return st;
34
0
}
35
36
37
/*[clinic input]
38
_symtable.symtable
39
40
    source:    object
41
    filename:  unicode_fs_decoded
42
    startstr:  str
43
    /
44
    *
45
    module as modname: object = None
46
47
Return symbol and scope dictionaries used internally by compiler.
48
49
The source can be a string, a bytes object, or an AST object.
50
[clinic start generated code]*/
51
52
static PyObject *
53
_symtable_symtable_impl(PyObject *module, PyObject *source,
54
                        PyObject *filename, const char *startstr,
55
                        PyObject *modname)
56
/*[clinic end generated code: output=235ec5a87a9ce178 input=6cadac0485f576a7]*/
57
0
{
58
0
    struct symtable *st;
59
0
    PyObject *t;
60
0
    int compile_mode;
61
62
0
    if (strcmp(startstr, "exec") == 0)
63
0
        compile_mode = 0;
64
0
    else if (strcmp(startstr, "eval") == 0)
65
0
        compile_mode = 1;
66
0
    else if (strcmp(startstr, "single") == 0)
67
0
        compile_mode = 2;
68
0
    else {
69
0
        PyErr_SetString(PyExc_ValueError,
70
0
           "symtable() arg 3 must be 'exec' or 'eval' or 'single'");
71
0
        return NULL;
72
0
    }
73
0
    if (modname == Py_None) {
74
0
        modname = NULL;
75
0
    }
76
0
    else if (!PyUnicode_Check(modname)) {
77
0
        PyErr_Format(PyExc_TypeError,
78
0
                     "symtable() argument 'module' must be str or None, not %T",
79
0
                     modname);
80
0
        return NULL;
81
0
    }
82
83
0
    if (PyAST_Check(source)) {
84
0
        st = symtable_from_ast(source, filename, compile_mode);
85
0
    }
86
0
    else {
87
0
        static const int starts[] = {
88
0
            Py_file_input, Py_eval_input, Py_single_input};
89
0
        PyCompilerFlags cf = _PyCompilerFlags_INIT;
90
0
        PyObject *source_copy = NULL;
91
92
0
        cf.cf_flags = PyCF_SOURCE_IS_UTF8;
93
0
        const char *str = _Py_SourceAsString(source, "symtable",
94
0
                                             "string, bytes or AST",
95
0
                                             &cf, &source_copy);
96
0
        if (str == NULL) {
97
0
            return NULL;
98
0
        }
99
0
        st = _Py_SymtableStringObjectFlags(str, filename,
100
0
                                           starts[compile_mode], &cf,
101
0
                                           modname);
102
0
        Py_XDECREF(source_copy);
103
0
    }
104
0
    if (st == NULL) {
105
0
        return NULL;
106
0
    }
107
0
    t = Py_NewRef(st->st_top);
108
0
    _PySymtable_Free(st);
109
0
    return t;
110
0
}
111
112
static PyMethodDef symtable_methods[] = {
113
    _SYMTABLE_SYMTABLE_METHODDEF
114
    {NULL,              NULL}           /* sentinel */
115
};
116
117
static int
118
symtable_init_constants(PyObject *m)
119
0
{
120
0
    if (PyModule_AddIntMacro(m, USE) < 0) return -1;
121
0
    if (PyModule_AddIntMacro(m, DEF_GLOBAL) < 0) return -1;
122
0
    if (PyModule_AddIntMacro(m, DEF_NONLOCAL) < 0) return -1;
123
0
    if (PyModule_AddIntMacro(m, DEF_LOCAL) < 0) return -1;
124
0
    if (PyModule_AddIntMacro(m, DEF_PARAM) < 0) return -1;
125
0
    if (PyModule_AddIntMacro(m, DEF_TYPE_PARAM) < 0) return -1;
126
0
    if (PyModule_AddIntMacro(m, DEF_FREE_CLASS) < 0) return -1;
127
0
    if (PyModule_AddIntMacro(m, DEF_IMPORT) < 0) return -1;
128
0
    if (PyModule_AddIntMacro(m, DEF_BOUND) < 0) return -1;
129
0
    if (PyModule_AddIntMacro(m, DEF_ANNOT) < 0) return -1;
130
0
    if (PyModule_AddIntMacro(m, DEF_COMP_ITER) < 0) return -1;
131
0
    if (PyModule_AddIntMacro(m, DEF_COMP_CELL) < 0) return -1;
132
133
0
    if (PyModule_AddIntConstant(m, "TYPE_FUNCTION", FunctionBlock) < 0)
134
0
        return -1;
135
0
    if (PyModule_AddIntConstant(m, "TYPE_CLASS", ClassBlock) < 0)
136
0
        return -1;
137
0
    if (PyModule_AddIntConstant(m, "TYPE_MODULE", ModuleBlock) < 0)
138
0
        return -1;
139
0
    if (PyModule_AddIntConstant(m, "TYPE_ANNOTATION", AnnotationBlock) < 0)
140
0
        return -1;
141
0
    if (PyModule_AddIntConstant(m, "TYPE_TYPE_ALIAS", TypeAliasBlock) < 0)
142
0
        return -1;
143
0
    if (PyModule_AddIntConstant(m, "TYPE_TYPE_PARAMETERS", TypeParametersBlock) < 0)
144
0
        return -1;
145
0
    if (PyModule_AddIntConstant(m, "TYPE_TYPE_VARIABLE", TypeVariableBlock) < 0)
146
0
        return -1;
147
148
0
    if (PyModule_AddIntMacro(m, LOCAL) < 0) return -1;
149
0
    if (PyModule_AddIntMacro(m, GLOBAL_EXPLICIT) < 0) return -1;
150
0
    if (PyModule_AddIntMacro(m, GLOBAL_IMPLICIT) < 0) return -1;
151
0
    if (PyModule_AddIntMacro(m, FREE) < 0) return -1;
152
0
    if (PyModule_AddIntMacro(m, CELL) < 0) return -1;
153
154
0
    if (PyModule_AddIntConstant(m, "SCOPE_OFF", SCOPE_OFFSET) < 0) return -1;
155
0
    if (PyModule_AddIntMacro(m, SCOPE_MASK) < 0) return -1;
156
157
0
    return 0;
158
0
}
159
160
static PyModuleDef_Slot symtable_slots[] = {
161
    _Py_ABI_SLOT,
162
    {Py_mod_exec, symtable_init_constants},
163
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
164
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
165
    {0, NULL}
166
};
167
168
static struct PyModuleDef symtablemodule = {
169
    PyModuleDef_HEAD_INIT,
170
    .m_name = "_symtable",
171
    .m_size = 0,
172
    .m_methods = symtable_methods,
173
    .m_slots = symtable_slots,
174
};
175
176
PyMODINIT_FUNC
177
PyInit__symtable(void)
178
0
{
179
0
    return PyModuleDef_Init(&symtablemodule);
180
0
}