Coverage Report

Created: 2026-05-30 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Python/intrinsics.c
Line
Count
Source
1
2
#define _PY_INTERPRETER
3
4
#include "Python.h"
5
#include "pycore_compile.h"       // _PyCompile_GetUnaryIntrinsicName
6
#include "pycore_function.h"      // _Py_set_function_type_params()
7
#include "pycore_genobject.h"     // _PyAsyncGenValueWrapperNew
8
#include "pycore_interpframe.h"   // _PyFrame_GetLocals()
9
#include "pycore_intrinsics.h"    // INTRINSIC_PRINT
10
#include "pycore_list.h"          // _PyList_AsTupleAndClear()
11
#include "pycore_object.h"        // _PyObject_IsUniquelyReferenced()
12
#include "pycore_setobject.h"     // _PySet_Freeze()
13
#include "pycore_pyerrors.h"      // _PyErr_SetString()
14
#include "pycore_runtime.h"       // _Py_ID()
15
#include "pycore_typevarobject.h" // _Py_make_typevar()
16
#include "pycore_unicodeobject.h" // _PyUnicode_FromASCII()
17
18
19
/******** Unary functions ********/
20
21
static PyObject *
22
no_intrinsic1(PyThreadState* tstate, PyObject *unused)
23
0
{
24
0
    _PyErr_SetString(tstate, PyExc_SystemError, "invalid intrinsic function");
25
0
    return NULL;
26
0
}
27
28
static PyObject *
29
print_expr(PyThreadState* Py_UNUSED(ignored), PyObject *value)
30
0
{
31
0
    PyObject *hook = PySys_GetAttr(&_Py_ID(displayhook));
32
0
    if (hook == NULL) {
33
0
        return NULL;
34
0
    }
35
0
    PyObject *res = PyObject_CallOneArg(hook, value);
36
0
    Py_DECREF(hook);
37
0
    return res;
38
0
}
39
40
static int
41
import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v)
42
456
{
43
456
    PyObject *all, *dict, *name, *value;
44
456
    int skip_leading_underscores = 0;
45
456
    int pos, err;
46
47
456
    if (PyObject_GetOptionalAttr(v, &_Py_ID(__all__), &all) < 0) {
48
0
        return -1; /* Unexpected error */
49
0
    }
50
456
    if (all == NULL) {
51
327
        if (PyObject_GetOptionalAttr(v, &_Py_ID(__dict__), &dict) < 0) {
52
0
            return -1;
53
0
        }
54
327
        if (dict == NULL) {
55
0
            _PyErr_SetString(tstate, PyExc_ImportError,
56
0
                    "from-import-* object has no __dict__ and no __all__");
57
0
            return -1;
58
0
        }
59
327
        all = PyMapping_Keys(dict);
60
327
        Py_DECREF(dict);
61
327
        if (all == NULL)
62
0
            return -1;
63
327
        skip_leading_underscores = 1;
64
327
    }
65
66
37.6k
    for (pos = 0, err = 0; ; pos++) {
67
37.6k
        name = PySequence_GetItem(all, pos);
68
37.6k
        if (name == NULL) {
69
456
            if (!_PyErr_ExceptionMatches(tstate, PyExc_IndexError)) {
70
0
                err = -1;
71
0
            }
72
456
            else {
73
456
                _PyErr_Clear(tstate);
74
456
            }
75
456
            break;
76
456
        }
77
37.1k
        if (!PyUnicode_Check(name)) {
78
0
            PyObject *modname = PyObject_GetAttr(v, &_Py_ID(__name__));
79
0
            if (modname == NULL) {
80
0
                Py_DECREF(name);
81
0
                err = -1;
82
0
                break;
83
0
            }
84
0
            if (!PyUnicode_Check(modname)) {
85
0
                _PyErr_Format(tstate, PyExc_TypeError,
86
0
                              "module __name__ must be a string, not %.100s",
87
0
                              Py_TYPE(modname)->tp_name);
88
0
            }
89
0
            else {
90
0
                _PyErr_Format(tstate, PyExc_TypeError,
91
0
                              "%s in %U.%s must be str, not %.100s",
92
0
                              skip_leading_underscores ? "Key" : "Item",
93
0
                              modname,
94
0
                              skip_leading_underscores ? "__dict__" : "__all__",
95
0
                              Py_TYPE(name)->tp_name);
96
0
            }
97
0
            Py_DECREF(modname);
98
0
            Py_DECREF(name);
99
0
            err = -1;
100
0
            break;
101
0
        }
102
37.1k
        if (skip_leading_underscores) {
103
35.4k
            if (PyUnicode_READ_CHAR(name, 0) == '_') {
104
2.37k
                Py_DECREF(name);
105
2.37k
                continue;
106
2.37k
            }
107
35.4k
        }
108
34.7k
        value = PyObject_GetAttr(v, name);
109
34.7k
        if (value == NULL)
110
0
            err = -1;
111
34.7k
        else if (PyDict_CheckExact(locals))
112
34.7k
            err = PyDict_SetItem(locals, name, value);
113
0
        else
114
0
            err = PyObject_SetItem(locals, name, value);
115
34.7k
        Py_DECREF(name);
116
34.7k
        Py_XDECREF(value);
117
34.7k
        if (err < 0)
118
0
            break;
119
34.7k
    }
120
456
    Py_DECREF(all);
121
456
    return err;
122
456
}
123
124
static PyObject *
125
import_star(PyThreadState* tstate, PyObject *from)
126
456
{
127
456
    _PyInterpreterFrame *frame = tstate->current_frame;
128
129
456
    PyObject *locals = _PyFrame_GetLocals(frame);
130
456
    if (locals == NULL) {
131
0
        _PyErr_SetString(tstate, PyExc_SystemError,
132
0
                            "no locals found during 'import *'");
133
0
        return NULL;
134
0
    }
135
456
    int err = import_all_from(tstate, locals, from);
136
456
    Py_DECREF(locals);
137
456
    if (err < 0) {
138
0
        return NULL;
139
0
    }
140
456
    Py_RETURN_NONE;
141
456
}
142
143
static PyObject *
144
stopiteration_error(PyThreadState* tstate, PyObject *exc)
145
66.5k
{
146
66.5k
    _PyInterpreterFrame *frame = tstate->current_frame;
147
66.5k
    assert(frame->owner == FRAME_OWNED_BY_GENERATOR);
148
66.5k
    assert(PyExceptionInstance_Check(exc));
149
66.5k
    const char *msg = NULL;
150
66.5k
    if (PyErr_GivenExceptionMatches(exc, PyExc_StopIteration)) {
151
0
        msg = "generator raised StopIteration";
152
0
        if (_PyFrame_GetCode(frame)->co_flags & CO_ASYNC_GENERATOR) {
153
0
            msg = "async generator raised StopIteration";
154
0
        }
155
0
        else if (_PyFrame_GetCode(frame)->co_flags & CO_COROUTINE) {
156
0
            msg = "coroutine raised StopIteration";
157
0
        }
158
0
    }
159
66.5k
    else if ((_PyFrame_GetCode(frame)->co_flags & CO_ASYNC_GENERATOR) &&
160
0
            PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration))
161
0
    {
162
        /* code in `gen` raised a StopAsyncIteration error:
163
        raise a RuntimeError.
164
        */
165
0
        msg = "async generator raised StopAsyncIteration";
166
0
    }
167
66.5k
    if (msg != NULL) {
168
0
        PyObject *message = _PyUnicode_FromASCII(msg, strlen(msg));
169
0
        if (message == NULL) {
170
0
            return NULL;
171
0
        }
172
0
        PyObject *error = PyObject_CallOneArg(PyExc_RuntimeError, message);
173
0
        if (error == NULL) {
174
0
            Py_DECREF(message);
175
0
            return NULL;
176
0
        }
177
0
        assert(PyExceptionInstance_Check(error));
178
0
        PyException_SetCause(error, Py_NewRef(exc));
179
        // Steal exc reference, rather than Py_NewRef+Py_DECREF
180
0
        PyException_SetContext(error, Py_NewRef(exc));
181
0
        Py_DECREF(message);
182
0
        return error;
183
0
    }
184
66.5k
    return Py_NewRef(exc);
185
66.5k
}
186
187
static PyObject *
188
unary_pos(PyThreadState* unused, PyObject *value)
189
0
{
190
0
    return PyNumber_Positive(value);
191
0
}
192
193
static PyObject *
194
list_to_tuple(PyThreadState* unused, PyObject *v)
195
9.85M
{
196
    /* INTRINSIC_LIST_TO_TUPLE is only emitted by the compiler for a
197
       freshly-built, uniquely-referenced temporary list, so steal its items
198
       into the tuple instead of copying them. */
199
9.85M
    assert(PyList_CheckExact(v));
200
9.85M
    assert(_PyObject_IsUniquelyReferenced(v));
201
9.85M
    return _PyList_AsTupleAndClear((PyListObject *)v);
202
9.85M
}
203
204
static PyObject *
205
make_typevar(PyThreadState* Py_UNUSED(ignored), PyObject *v)
206
32
{
207
32
    assert(PyUnicode_Check(v));
208
32
    return _Py_make_typevar(v, NULL, NULL);
209
32
}
210
211
static PyObject *
212
make_frozenset(PyThreadState* Py_UNUSED(ignored), PyObject *set)
213
127
{
214
127
    assert(PySet_CheckExact(set));
215
127
    assert(_PyObject_IsUniquelyReferenced(set));
216
127
    return _PySet_Freeze(set);
217
127
}
218
219
220
#define INTRINSIC_FUNC_ENTRY(N, F) \
221
    [N] = {F, #N},
222
223
const intrinsic_func1_info
224
_PyIntrinsics_UnaryFunctions[] = {
225
    INTRINSIC_FUNC_ENTRY(INTRINSIC_1_INVALID, no_intrinsic1)
226
    INTRINSIC_FUNC_ENTRY(INTRINSIC_PRINT, print_expr)
227
    INTRINSIC_FUNC_ENTRY(INTRINSIC_IMPORT_STAR, import_star)
228
    INTRINSIC_FUNC_ENTRY(INTRINSIC_STOPITERATION_ERROR, stopiteration_error)
229
    INTRINSIC_FUNC_ENTRY(INTRINSIC_ASYNC_GEN_WRAP, _PyAsyncGenValueWrapperNew)
230
    INTRINSIC_FUNC_ENTRY(INTRINSIC_UNARY_POSITIVE, unary_pos)
231
    INTRINSIC_FUNC_ENTRY(INTRINSIC_LIST_TO_TUPLE, list_to_tuple)
232
    INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEVAR, make_typevar)
233
    INTRINSIC_FUNC_ENTRY(INTRINSIC_PARAMSPEC, _Py_make_paramspec)
234
    INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEVARTUPLE, _Py_make_typevartuple)
235
    INTRINSIC_FUNC_ENTRY(INTRINSIC_SUBSCRIPT_GENERIC, _Py_subscript_generic)
236
    INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEALIAS, _Py_make_typealias)
237
    INTRINSIC_FUNC_ENTRY(INTRINSIC_BUILD_FROZENSET, make_frozenset)
238
};
239
240
241
/******** Binary functions ********/
242
243
static PyObject *
244
no_intrinsic2(PyThreadState* tstate, PyObject *unused1, PyObject *unused2)
245
0
{
246
0
    _PyErr_SetString(tstate, PyExc_SystemError, "invalid intrinsic function");
247
0
    return NULL;
248
0
}
249
250
static PyObject *
251
prep_reraise_star(PyThreadState* unused, PyObject *orig, PyObject *excs)
252
0
{
253
0
    assert(PyList_Check(excs));
254
0
    return _PyExc_PrepReraiseStar(orig, excs);
255
0
}
256
257
static PyObject *
258
make_typevar_with_bound(PyThreadState* Py_UNUSED(ignored), PyObject *name,
259
                        PyObject *evaluate_bound)
260
8
{
261
8
    assert(PyUnicode_Check(name));
262
8
    return _Py_make_typevar(name, evaluate_bound, NULL);
263
8
}
264
265
static PyObject *
266
make_typevar_with_constraints(PyThreadState* Py_UNUSED(ignored), PyObject *name,
267
                              PyObject *evaluate_constraints)
268
0
{
269
0
    assert(PyUnicode_Check(name));
270
0
    return _Py_make_typevar(name, NULL, evaluate_constraints);
271
0
}
272
273
const intrinsic_func2_info
274
_PyIntrinsics_BinaryFunctions[] = {
275
    INTRINSIC_FUNC_ENTRY(INTRINSIC_2_INVALID, no_intrinsic2)
276
    INTRINSIC_FUNC_ENTRY(INTRINSIC_PREP_RERAISE_STAR, prep_reraise_star)
277
    INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEVAR_WITH_BOUND, make_typevar_with_bound)
278
    INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEVAR_WITH_CONSTRAINTS, make_typevar_with_constraints)
279
    INTRINSIC_FUNC_ENTRY(INTRINSIC_SET_FUNCTION_TYPE_PARAMS, _Py_set_function_type_params)
280
    INTRINSIC_FUNC_ENTRY(INTRINSIC_SET_TYPEPARAM_DEFAULT, _Py_set_typeparam_default)
281
};
282
283
#undef INTRINSIC_FUNC_ENTRY
284
285
PyObject*
286
_PyCompile_GetUnaryIntrinsicName(int index)
287
78
{
288
78
    if (index < 0 || index > MAX_INTRINSIC_1) {
289
0
        return NULL;
290
0
    }
291
78
    return PyUnicode_FromString(_PyIntrinsics_UnaryFunctions[index].name);
292
78
}
293
294
PyObject*
295
_PyCompile_GetBinaryIntrinsicName(int index)
296
36
{
297
36
    if (index < 0 || index > MAX_INTRINSIC_2) {
298
0
        return NULL;
299
0
    }
300
36
    return PyUnicode_FromString(_PyIntrinsics_BinaryFunctions[index].name);
301
36
}