Coverage Report

Created: 2025-10-12 06:48

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