Coverage Report

Created: 2025-07-04 06:49

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