Coverage Report

Created: 2026-10-17 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Python/sysmodule.c
Line
Count
Source
1
2
/* System module */
3
4
/*
5
Various bits of information used by the interpreter are collected in
6
module 'sys'.
7
Function member:
8
- exit(sts): raise SystemExit
9
Data members:
10
- stdin, stdout, stderr: standard file objects
11
- modules: the table of modules (dictionary)
12
- path: module search path (list of strings)
13
- argv: script arguments (list of strings)
14
- ps1, ps2: optional primary and secondary prompts (strings)
15
*/
16
17
#include "Python.h"
18
#include "pycore_audit.h"         // _Py_AuditHookEntry
19
#include "pycore_call.h"          // _PyObject_CallNoArgs()
20
#include "pycore_ceval.h"         // _PyEval_SetAsyncGenFinalizer()
21
#include "pycore_frame.h"         // _PyInterpreterFrame
22
#include "pycore_import.h"        // _PyImport_SetDLOpenFlags()
23
#include "pycore_initconfig.h"    // _PyStatus_EXCEPTION()
24
#include "pycore_interpframe.h"   // _PyFrame_GetFirstComplete()
25
#include "pycore_long.h"          // _PY_LONG_MAX_STR_DIGITS_THRESHOLD
26
#include "pycore_modsupport.h"    // _PyModule_CreateInitialized()
27
#include "pycore_namespace.h"     // _PyNamespace_New()
28
#include "pycore_object.h"        // _PyObject_DebugTypeStats()
29
#include "pycore_optimizer.h"     // _PyDumpExecutors()
30
#include "pycore_pathconfig.h"    // _PyPathConfig_ComputeSysPath0()
31
#include "pycore_pyerrors.h"      // _PyErr_GetRaisedException()
32
#include "pycore_pylifecycle.h"   // _PyErr_WriteUnraisableDefaultHook()
33
#include "pycore_pymath.h"        // _PY_SHORT_FLOAT_REPR
34
#include "pycore_pymem.h"         // _PyMem_DefaultRawFree()
35
#include "pycore_pystate.h"       // _PyThreadState_GET()
36
#include "pycore_pystats.h"       // _Py_PrintSpecializationStats()
37
#include "pycore_runtime.h"       // _PyRuntimeState_Get*()
38
#include "pycore_structseq.h"     // _PyStructSequence_InitBuiltinWithFlags()
39
#include "pycore_sysmodule.h"     // export _PySys_GetSizeOf()
40
#include "pycore_unicodeobject.h" // _PyUnicode_InternImmortal()
41
42
#include "pydtrace.h"             // PyDTrace_AUDIT()
43
#include "osdefs.h"               // DELIM
44
#include "stdlib_module_names.h"  // _Py_stdlib_module_names
45
46
#ifdef HAVE_UNISTD_H
47
#  include <unistd.h>             // getpid()
48
#endif
49
50
#ifdef MS_WINDOWS
51
#  ifndef WIN32_LEAN_AND_MEAN
52
#    define WIN32_LEAN_AND_MEAN
53
#  endif
54
#  include <windows.h>
55
#endif /* MS_WINDOWS */
56
57
#ifdef MS_COREDLL
58
extern void *PyWin_DLLhModule;
59
/* A string loaded from the DLL at startup: */
60
extern const char *PyWin_DLLVersionString;
61
#endif
62
63
#ifdef __EMSCRIPTEN__
64
#  include <emscripten.h>
65
#endif
66
67
#ifdef __wasi__
68
#  include <wasi/version.h>
69
#endif
70
71
#ifdef HAVE_FCNTL_H
72
#  include <fcntl.h>
73
#endif
74
75
/*[clinic input]
76
module sys
77
[clinic start generated code]*/
78
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3726b388feee8cea]*/
79
80
#include "clinic/sysmodule.c.h"
81
82
83
PyObject *
84
PySys_GetAttr(PyObject *name)
85
0
{
86
0
    if (!PyUnicode_Check(name)) {
87
0
        PyErr_Format(PyExc_TypeError,
88
0
                     "attribute name must be string, not '%T'",
89
0
                     name);
90
0
        return NULL;
91
0
    }
92
0
    PyThreadState *tstate = _PyThreadState_GET();
93
0
    PyObject *sysdict = tstate->interp->sysdict;
94
0
    if (sysdict == NULL) {
95
0
        PyErr_SetString(PyExc_RuntimeError, "no sys module");
96
0
        return NULL;
97
0
    }
98
0
    PyObject *value;
99
0
    if (PyDict_GetItemRef(sysdict, name, &value) == 0) {
100
0
        PyErr_Format(PyExc_RuntimeError, "lost sys.%U", name);
101
0
    }
102
0
    return value;
103
0
}
104
105
PyObject *
106
PySys_GetAttrString(const char *name)
107
37
{
108
37
    PyThreadState *tstate = _PyThreadState_GET();
109
37
    PyObject *sysdict = tstate->interp->sysdict;
110
37
    if (sysdict == NULL) {
111
0
        PyErr_SetString(PyExc_RuntimeError, "no sys module");
112
0
        return NULL;
113
0
    }
114
37
    PyObject *value;
115
37
    if (PyDict_GetItemStringRef(sysdict, name, &value) == 0) {
116
0
        PyErr_Format(PyExc_RuntimeError, "lost sys.%s", name);
117
0
    }
118
37
    return value;
119
37
}
120
121
int
122
PySys_GetOptionalAttr(PyObject *name, PyObject **value)
123
0
{
124
0
    if (!PyUnicode_Check(name)) {
125
0
        PyErr_Format(PyExc_TypeError,
126
0
                     "attribute name must be string, not '%T'",
127
0
                     name);
128
0
        *value = NULL;
129
0
        return -1;
130
0
    }
131
0
    PyThreadState *tstate = _PyThreadState_GET();
132
0
    PyObject *sysdict = tstate->interp->sysdict;
133
0
    if (sysdict == NULL) {
134
0
        *value = NULL;
135
0
        return 0;
136
0
    }
137
0
    return PyDict_GetItemRef(sysdict, name, value);
138
0
}
139
140
int
141
PySys_GetOptionalAttrString(const char *name, PyObject **value)
142
37
{
143
37
    PyThreadState *tstate = _PyThreadState_GET();
144
37
    PyObject *sysdict = tstate->interp->sysdict;
145
37
    if (sysdict == NULL) {
146
0
        *value = NULL;
147
0
        return 0;
148
0
    }
149
37
    return PyDict_GetItemStringRef(sysdict, name, value);
150
37
}
151
152
PyObject *
153
PySys_GetObject(const char *name)
154
0
{
155
0
    PyThreadState *tstate = _PyThreadState_GET();
156
0
    PyObject *sysdict = tstate->interp->sysdict;
157
0
    if (sysdict == NULL) {
158
0
        return NULL;
159
0
    }
160
0
    PyObject *exc = _PyErr_GetRaisedException(tstate);
161
0
    PyObject *value;
162
0
    (void) PyDict_GetItemStringRef(sysdict, name, &value);
163
    /* XXX Suppress a new exception if it was raised and restore
164
     * the old one. */
165
0
    if (_PyErr_Occurred(tstate)) {
166
0
        PyErr_FormatUnraisable("Exception ignored in PySys_GetObject()");
167
0
    }
168
0
    _PyErr_SetRaisedException(tstate, exc);
169
0
    Py_XDECREF(value);  // return a borrowed reference
170
0
    return value;
171
0
}
172
173
static int
174
sys_set_object(PyInterpreterState *interp, PyObject *key, PyObject *v)
175
259
{
176
259
    if (key == NULL) {
177
0
        return -1;
178
0
    }
179
259
    PyObject *sd = interp->sysdict;
180
259
    if (sd == NULL) {
181
0
        PyErr_SetString(PyExc_RuntimeError, "no sys module");
182
0
        return -1;
183
0
    }
184
259
    if (v == NULL) {
185
0
        if (PyDict_Pop(sd, key, NULL) < 0) {
186
0
            return -1;
187
0
        }
188
0
        return 0;
189
0
    }
190
259
    else {
191
259
        return PyDict_SetItem(sd, key, v);
192
259
    }
193
259
}
194
195
int
196
_PySys_SetAttr(PyObject *key, PyObject *v)
197
148
{
198
148
    PyInterpreterState *interp = _PyInterpreterState_GET();
199
148
    return sys_set_object(interp, key, v);
200
148
}
201
202
static int
203
sys_set_object_str(PyInterpreterState *interp, const char *name, PyObject *v)
204
111
{
205
111
    PyObject *key = v ? PyUnicode_InternFromString(name)
206
111
                      : PyUnicode_FromString(name);
207
111
    int r = sys_set_object(interp, key, v);
208
111
    Py_XDECREF(key);
209
111
    return r;
210
111
}
211
212
int
213
PySys_SetObject(const char *name, PyObject *v)
214
111
{
215
111
    PyInterpreterState *interp = _PyInterpreterState_GET();
216
111
    return sys_set_object_str(interp, name, v);
217
111
}
218
219
int
220
_PySys_ClearAttrString(PyInterpreterState *interp,
221
                       const char *name, int verbose)
222
0
{
223
0
    if (verbose) {
224
0
        PySys_WriteStderr("# clear sys.%s\n", name);
225
0
    }
226
    /* To play it safe, we set the attr to None instead of deleting it. */
227
0
    if (PyDict_SetItemString(interp->sysdict, name, Py_None) < 0) {
228
0
        return -1;
229
0
    }
230
0
    return 0;
231
0
}
232
233
234
static int
235
should_audit(PyInterpreterState *interp)
236
979k
{
237
    /* interp must not be NULL, but test it just in case for extra safety */
238
979k
    assert(interp != NULL);
239
979k
    if (!interp) {
240
0
        return 0;
241
0
    }
242
979k
    return (interp->runtime->audit_hooks.head
243
979k
            || interp->audit_hooks
244
547k
            || PyDTrace_AUDIT_ENABLED());
245
979k
}
246
247
248
static int
249
sys_audit_tstate(PyThreadState *ts, const char *event,
250
                 const char *argFormat, va_list vargs)
251
955k
{
252
955k
    assert(event != NULL);
253
955k
    assert(!argFormat || !strchr(argFormat, 'N'));
254
255
955k
    if (!ts) {
256
        /* Audit hooks cannot be called with a NULL thread state */
257
0
        return 0;
258
0
    }
259
260
    /* The current implementation cannot be called if tstate is not
261
       the current Python thread state. */
262
955k
    assert(ts == _PyThreadState_GET());
263
264
    /* Early exit when no hooks are registered */
265
955k
    PyInterpreterState *is = ts->interp;
266
955k
    if (!should_audit(is)) {
267
537k
        return 0;
268
537k
    }
269
270
418k
    PyObject *eventName = NULL;
271
418k
    PyObject *eventArgs = NULL;
272
418k
    PyObject *hooks = NULL;
273
418k
    PyObject *hook = NULL;
274
418k
    int res = -1;
275
276
418k
    int dtrace = PyDTrace_AUDIT_ENABLED();
277
278
279
418k
    PyObject *exc = _PyErr_GetRaisedException(ts);
280
281
    /* Initialize event args now */
282
418k
    if (argFormat && argFormat[0]) {
283
418k
        eventArgs = Py_VaBuildValue(argFormat, vargs);
284
418k
        if (eventArgs && !PyTuple_Check(eventArgs)) {
285
92.7k
            PyObject *argTuple = PyTuple_Pack(1, eventArgs);
286
92.7k
            Py_SETREF(eventArgs, argTuple);
287
92.7k
        }
288
418k
    }
289
0
    else {
290
0
        eventArgs = PyTuple_New(0);
291
0
    }
292
418k
    if (!eventArgs) {
293
0
        goto exit;
294
0
    }
295
296
    /* Call global hooks
297
     *
298
     * We don't worry about any races on hooks getting added,
299
     * since that would not leave is in an inconsistent state. */
300
418k
    _Py_AuditHookEntry *e = is->runtime->audit_hooks.head;
301
418k
    for (; e; e = e->next) {
302
0
        if (e->hookCFunction(event, eventArgs, e->userData) < 0) {
303
0
            goto exit;
304
0
        }
305
0
    }
306
307
    /* Dtrace USDT point */
308
418k
    if (dtrace) {
309
0
        PyDTrace_AUDIT(event, (void *)eventArgs);
310
0
    }
311
312
    /* Call interpreter hooks */
313
418k
    if (is->audit_hooks) {
314
418k
        eventName = PyUnicode_FromString(event);
315
418k
        if (!eventName) {
316
0
            goto exit;
317
0
        }
318
319
418k
        hooks = PyObject_GetIter(is->audit_hooks);
320
418k
        if (!hooks) {
321
0
            goto exit;
322
0
        }
323
324
        /* Disallow tracing in hooks unless explicitly enabled */
325
418k
        PyThreadState_EnterTracing(ts);
326
836k
        while ((hook = PyIter_Next(hooks)) != NULL) {
327
418k
            PyObject *o;
328
418k
            int canTrace = PyObject_GetOptionalAttr(hook, &_Py_ID(__cantrace__), &o);
329
418k
            if (o) {
330
0
                canTrace = PyObject_IsTrue(o);
331
0
                Py_DECREF(o);
332
0
            }
333
418k
            if (canTrace < 0) {
334
0
                break;
335
0
            }
336
418k
            if (canTrace) {
337
0
                PyThreadState_LeaveTracing(ts);
338
0
            }
339
418k
            PyObject* args[2] = {eventName, eventArgs};
340
418k
            o = _PyObject_VectorcallTstate(ts, hook, args, 2, NULL);
341
418k
            if (canTrace) {
342
0
                PyThreadState_EnterTracing(ts);
343
0
            }
344
418k
            if (!o) {
345
0
                break;
346
0
            }
347
418k
            Py_DECREF(o);
348
418k
            Py_CLEAR(hook);
349
418k
        }
350
418k
        PyThreadState_LeaveTracing(ts);
351
418k
        if (_PyErr_Occurred(ts)) {
352
0
            goto exit;
353
0
        }
354
418k
    }
355
356
418k
    res = 0;
357
358
418k
exit:
359
418k
    Py_XDECREF(hook);
360
418k
    Py_XDECREF(hooks);
361
418k
    Py_XDECREF(eventName);
362
418k
    Py_XDECREF(eventArgs);
363
364
418k
    if (!res) {
365
418k
        _PyErr_SetRaisedException(ts, exc);
366
418k
    }
367
0
    else {
368
0
        assert(_PyErr_Occurred(ts));
369
0
        Py_XDECREF(exc);
370
0
    }
371
372
418k
    return res;
373
418k
}
374
375
int
376
_PySys_Audit(PyThreadState *tstate, const char *event,
377
             const char *argFormat, ...)
378
35.9k
{
379
35.9k
    va_list vargs;
380
35.9k
    va_start(vargs, argFormat);
381
35.9k
    int res = sys_audit_tstate(tstate, event, argFormat, vargs);
382
35.9k
    va_end(vargs);
383
35.9k
    return res;
384
35.9k
}
385
386
int
387
PySys_Audit(const char *event, const char *argFormat, ...)
388
919k
{
389
919k
    PyThreadState *tstate = _PyThreadState_GET();
390
919k
    va_list vargs;
391
919k
    va_start(vargs, argFormat);
392
919k
    int res = sys_audit_tstate(tstate, event, argFormat, vargs);
393
919k
    va_end(vargs);
394
919k
    return res;
395
919k
}
396
397
int
398
PySys_AuditTuple(const char *event, PyObject *args)
399
0
{
400
0
    if (args == NULL) {
401
0
        return PySys_Audit(event, NULL);
402
0
    }
403
404
0
    if (!PyTuple_Check(args)) {
405
0
        PyErr_Format(PyExc_TypeError, "args must be tuple, got %s",
406
0
                     Py_TYPE(args)->tp_name);
407
0
        return -1;
408
0
    }
409
0
    return PySys_Audit(event, "O", args);
410
0
}
411
412
/* We expose this function primarily for our own cleanup during
413
 * finalization. In general, it should not need to be called,
414
 * and as such the function is not exported.
415
 *
416
 * Must be finalizing to clear hooks */
417
void
418
_PySys_ClearAuditHooks(PyThreadState *ts)
419
0
{
420
0
    assert(ts != NULL);
421
0
    if (!ts) {
422
0
        return;
423
0
    }
424
425
0
    _PyRuntimeState *runtime = ts->interp->runtime;
426
    /* The hooks are global so we have to check for runtime finalization. */
427
0
    PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime);
428
0
    assert(finalizing == ts);
429
0
    if (finalizing != ts) {
430
0
        return;
431
0
    }
432
433
0
    const PyConfig *config = _PyInterpreterState_GetConfig(ts->interp);
434
0
    if (config->verbose) {
435
0
        PySys_WriteStderr("# clear sys.audit hooks\n");
436
0
    }
437
438
    /* Hooks can abort later hooks for this event, but cannot
439
       abort the clear operation itself. */
440
0
    _PySys_Audit(ts, "cpython._PySys_ClearAuditHooks", NULL);
441
0
    _PyErr_Clear(ts);
442
443
    /* We don't worry about the very unlikely race right here,
444
     * since it's entirely benign.  Nothing else removes entries
445
     * from the list and adding an entry right now would not cause
446
     * any trouble. */
447
0
    _Py_AuditHookEntry *e = runtime->audit_hooks.head, *n;
448
0
    runtime->audit_hooks.head = NULL;
449
0
    while (e) {
450
0
        n = e->next;
451
0
        PyMem_RawFree(e);
452
0
        e = n;
453
0
    }
454
0
}
455
456
static void
457
add_audit_hook_entry_unlocked(_PyRuntimeState *runtime,
458
                              _Py_AuditHookEntry *entry)
459
0
{
460
0
    if (runtime->audit_hooks.head == NULL) {
461
0
        runtime->audit_hooks.head = entry;
462
0
    }
463
0
    else {
464
0
        _Py_AuditHookEntry *last = runtime->audit_hooks.head;
465
0
        while (last->next) {
466
0
            last = last->next;
467
0
        }
468
0
        last->next = entry;
469
0
    }
470
0
}
471
472
int
473
PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
474
0
{
475
    /* tstate can be NULL, so access directly _PyRuntime:
476
       PySys_AddAuditHook() can be called before Python is initialized. */
477
0
    _PyRuntimeState *runtime = &_PyRuntime;
478
0
    PyThreadState *tstate;
479
0
    if (_PyRuntimeState_GetInitialized(runtime)) {
480
0
        tstate = _PyThreadState_GET();
481
0
    }
482
0
    else {
483
0
        tstate = NULL;
484
0
    }
485
486
    /* Invoke existing audit hooks to allow them an opportunity to abort. */
487
    /* Cannot invoke hooks until we are initialized */
488
0
    if (tstate != NULL) {
489
0
        if (_PySys_Audit(tstate, "sys.addaudithook", NULL) < 0) {
490
0
            if (_PyErr_ExceptionMatches(tstate, PyExc_RuntimeError)) {
491
                /* We do not report errors derived from RuntimeError */
492
0
                _PyErr_Clear(tstate);
493
0
                return 0;
494
0
            }
495
0
            return -1;
496
0
        }
497
0
    }
498
499
0
    _Py_AuditHookEntry *e = (_Py_AuditHookEntry*)PyMem_RawMalloc(
500
0
            sizeof(_Py_AuditHookEntry));
501
0
    if (!e) {
502
0
        if (tstate != NULL) {
503
0
            _PyErr_NoMemory(tstate);
504
0
        }
505
0
        return -1;
506
0
    }
507
0
    e->next = NULL;
508
0
    e->hookCFunction = (Py_AuditHookFunction)hook;
509
0
    e->userData = userData;
510
511
0
    PyMutex_Lock(&runtime->audit_hooks.mutex);
512
0
    add_audit_hook_entry_unlocked(runtime, e);
513
0
    PyMutex_Unlock(&runtime->audit_hooks.mutex);
514
515
0
    return 0;
516
0
}
517
518
/*[clinic input]
519
sys.addaudithook
520
521
    hook: object
522
523
Adds a new audit hook callback.
524
[clinic start generated code]*/
525
526
static PyObject *
527
sys_addaudithook_impl(PyObject *module, PyObject *hook)
528
/*[clinic end generated code: output=4f9c17aaeb02f44e input=0f3e191217a45e34]*/
529
4
{
530
4
    PyThreadState *tstate = _PyThreadState_GET();
531
532
    /* Invoke existing audit hooks to allow them an opportunity to abort. */
533
4
    if (_PySys_Audit(tstate, "sys.addaudithook", NULL) < 0) {
534
0
        if (_PyErr_ExceptionMatches(tstate, PyExc_RuntimeError)) {
535
            /* We do not report errors derived from RuntimeError */
536
0
            _PyErr_Clear(tstate);
537
0
            Py_RETURN_NONE;
538
0
        }
539
0
        return NULL;
540
0
    }
541
542
4
    PyInterpreterState *interp = tstate->interp;
543
4
    if (interp->audit_hooks == NULL) {
544
4
        interp->audit_hooks = PyList_New(0);
545
4
        if (interp->audit_hooks == NULL) {
546
0
            return NULL;
547
0
        }
548
        /* Avoid having our list of hooks show up in the GC module */
549
4
        PyObject_GC_UnTrack(interp->audit_hooks);
550
4
    }
551
552
4
    if (PyList_Append(interp->audit_hooks, hook) < 0) {
553
0
        return NULL;
554
0
    }
555
556
4
    Py_RETURN_NONE;
557
4
}
558
559
/*[clinic input]
560
sys.audit
561
562
    event: str
563
    /
564
    *args: tuple
565
566
Passes the event to any audit hooks that are attached.
567
[clinic start generated code]*/
568
569
static PyObject *
570
sys_audit_impl(PyObject *module, const char *event, PyObject *args)
571
/*[clinic end generated code: output=1d0fc82da768f49d input=ec3b688527945109]*/
572
24.4k
{
573
24.4k
    PyThreadState *tstate = _PyThreadState_GET();
574
24.4k
    _Py_EnsureTstateNotNULL(tstate);
575
576
24.4k
    if (!should_audit(tstate->interp)) {
577
10.4k
        Py_RETURN_NONE;
578
10.4k
    }
579
580
14.0k
    int res = _PySys_Audit(tstate, event, "O", args);
581
14.0k
    if (res < 0) {
582
0
        return NULL;
583
0
    }
584
585
14.0k
    Py_RETURN_NONE;
586
14.0k
}
587
588
589
static PyObject *
590
sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords)
591
0
{
592
0
    PyThreadState *tstate = _PyThreadState_GET();
593
0
    assert(!_PyErr_Occurred(tstate));
594
0
    char *envar = Py_GETENV("PYTHONBREAKPOINT");
595
596
0
    if (envar == NULL || strlen(envar) == 0) {
597
0
        envar = "pdb.set_trace";
598
0
    }
599
0
    else if (!strcmp(envar, "0")) {
600
        /* The breakpoint is explicitly no-op'd. */
601
0
        Py_RETURN_NONE;
602
0
    }
603
    /* According to POSIX the string returned by getenv() might be invalidated
604
     * or the string content might be overwritten by a subsequent call to
605
     * getenv().  Since importing a module can performs the getenv() calls,
606
     * we need to save a copy of envar. */
607
0
    envar = _PyMem_RawStrdup(envar);
608
0
    if (envar == NULL) {
609
0
        _PyErr_NoMemory(tstate);
610
0
        return NULL;
611
0
    }
612
0
    const char *last_dot = strrchr(envar, '.');
613
0
    const char *attrname = NULL;
614
0
    PyObject *modulepath = NULL;
615
616
0
    if (last_dot == NULL) {
617
        /* The breakpoint is a built-in, e.g. PYTHONBREAKPOINT=int */
618
0
        modulepath = &_Py_ID(builtins);
619
0
        attrname = envar;
620
0
    }
621
0
    else if (last_dot != envar) {
622
        /* Split on the last dot; */
623
0
        modulepath = PyUnicode_FromStringAndSize(envar, last_dot - envar);
624
0
        attrname = last_dot + 1;
625
0
    }
626
0
    else {
627
0
        goto warn;
628
0
    }
629
0
    if (modulepath == NULL) {
630
0
        PyMem_RawFree(envar);
631
0
        return NULL;
632
0
    }
633
634
0
    PyObject *module = PyImport_Import(modulepath);
635
0
    Py_DECREF(modulepath);
636
637
0
    if (module == NULL) {
638
0
        if (_PyErr_ExceptionMatches(tstate, PyExc_ImportError)) {
639
0
            goto warn;
640
0
        }
641
0
        PyMem_RawFree(envar);
642
0
        return NULL;
643
0
    }
644
645
0
    PyObject *hook = PyObject_GetAttrString(module, attrname);
646
0
    Py_DECREF(module);
647
648
0
    if (hook == NULL) {
649
0
        if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
650
0
            goto warn;
651
0
        }
652
0
        PyMem_RawFree(envar);
653
0
        return NULL;
654
0
    }
655
0
    PyMem_RawFree(envar);
656
0
    PyObject *retval = PyObject_Vectorcall(hook, args, nargs, keywords);
657
0
    Py_DECREF(hook);
658
0
    return retval;
659
660
0
  warn:
661
    /* If any of the imports went wrong, then warn and ignore. */
662
0
    _PyErr_Clear(tstate);
663
0
    int status = PyErr_WarnFormat(
664
0
        PyExc_RuntimeWarning, 0,
665
0
        "Ignoring unimportable $PYTHONBREAKPOINT: \"%s\"", envar);
666
0
    PyMem_RawFree(envar);
667
0
    if (status < 0) {
668
        /* Printing the warning raised an exception. */
669
0
        return NULL;
670
0
    }
671
    /* The warning was (probably) issued. */
672
0
    Py_RETURN_NONE;
673
0
}
674
675
PyDoc_STRVAR(breakpointhook_doc,
676
"breakpointhook($module, /, *args, **kwargs)\n"
677
"--\n"
678
"\n"
679
"This hook function is called by built-in breakpoint().\n"
680
);
681
682
/* Write repr(o) to sys.stdout using sys.stdout.encoding and 'backslashreplace'
683
   error handler. If sys.stdout has a buffer attribute, use
684
   sys.stdout.buffer.write(encoded), otherwise redecode the string and use
685
   sys.stdout.write(redecoded).
686
687
   Helper function for sys_displayhook(). */
688
static int
689
sys_displayhook_unencodable(PyObject *outf, PyObject *o)
690
0
{
691
0
    PyObject *stdout_encoding = NULL;
692
0
    PyObject *encoded, *escaped_str, *repr_str, *buffer, *result;
693
0
    const char *stdout_encoding_str;
694
0
    int ret;
695
696
0
    stdout_encoding = PyObject_GetAttr(outf, &_Py_ID(encoding));
697
0
    if (stdout_encoding == NULL)
698
0
        goto error;
699
0
    stdout_encoding_str = PyUnicode_AsUTF8(stdout_encoding);
700
0
    if (stdout_encoding_str == NULL)
701
0
        goto error;
702
703
0
    repr_str = PyObject_Repr(o);
704
0
    if (repr_str == NULL)
705
0
        goto error;
706
0
    encoded = PyUnicode_AsEncodedString(repr_str,
707
0
                                        stdout_encoding_str,
708
0
                                        "backslashreplace");
709
0
    Py_DECREF(repr_str);
710
0
    if (encoded == NULL)
711
0
        goto error;
712
713
0
    if (PyObject_GetOptionalAttr(outf, &_Py_ID(buffer), &buffer) < 0) {
714
0
        Py_DECREF(encoded);
715
0
        goto error;
716
0
    }
717
0
    if (buffer) {
718
0
        result = PyObject_CallMethodOneArg(buffer, &_Py_ID(write), encoded);
719
0
        Py_DECREF(buffer);
720
0
        Py_DECREF(encoded);
721
0
        if (result == NULL)
722
0
            goto error;
723
0
        Py_DECREF(result);
724
0
    }
725
0
    else {
726
0
        escaped_str = PyUnicode_FromEncodedObject(encoded,
727
0
                                                  stdout_encoding_str,
728
0
                                                  "strict");
729
0
        Py_DECREF(encoded);
730
0
        if (PyFile_WriteObject(escaped_str, outf, Py_PRINT_RAW) != 0) {
731
0
            Py_DECREF(escaped_str);
732
0
            goto error;
733
0
        }
734
0
        Py_DECREF(escaped_str);
735
0
    }
736
0
    ret = 0;
737
0
    goto finally;
738
739
0
error:
740
0
    ret = -1;
741
0
finally:
742
0
    Py_XDECREF(stdout_encoding);
743
0
    return ret;
744
0
}
745
746
/*[clinic input]
747
sys.displayhook
748
749
    object as o: object
750
    /
751
752
Print an object to sys.stdout and also save it in builtins._
753
[clinic start generated code]*/
754
755
static PyObject *
756
sys_displayhook(PyObject *module, PyObject *o)
757
/*[clinic end generated code: output=347477d006df92ed input=08ba730166d7ef72]*/
758
0
{
759
0
    PyObject *outf;
760
0
    PyObject *builtins;
761
0
    PyThreadState *tstate = _PyThreadState_GET();
762
763
0
    builtins = PyImport_GetModule(&_Py_ID(builtins));
764
0
    if (builtins == NULL) {
765
0
        if (!_PyErr_Occurred(tstate)) {
766
0
            _PyErr_SetString(tstate, PyExc_RuntimeError,
767
0
                             "lost builtins module");
768
0
        }
769
0
        return NULL;
770
0
    }
771
0
    Py_DECREF(builtins);
772
773
    /* Print value except if None */
774
    /* After printing, also assign to '_' */
775
    /* Before, set '_' to None to avoid recursion */
776
0
    if (o == Py_None) {
777
0
        Py_RETURN_NONE;
778
0
    }
779
0
    if (PyObject_SetAttr(builtins, _Py_LATIN1_CHR('_'), Py_None) != 0)
780
0
        return NULL;
781
0
    outf = PySys_GetAttr(&_Py_ID(stdout));
782
0
    if (outf == NULL) {
783
0
        return NULL;
784
0
    }
785
0
    if (outf == Py_None) {
786
0
        _PyErr_SetString(tstate, PyExc_RuntimeError, "lost sys.stdout");
787
0
        Py_DECREF(outf);
788
0
        return NULL;
789
0
    }
790
0
    if (PyFile_WriteObject(o, outf, 0) != 0) {
791
0
        if (_PyErr_ExceptionMatches(tstate, PyExc_UnicodeEncodeError)) {
792
0
            int err;
793
            /* repr(o) is not encodable to sys.stdout.encoding with
794
             * sys.stdout.errors error handler (which is probably 'strict') */
795
0
            _PyErr_Clear(tstate);
796
0
            err = sys_displayhook_unencodable(outf, o);
797
0
            if (err) {
798
0
                Py_DECREF(outf);
799
0
                return NULL;
800
0
            }
801
0
        }
802
0
        else {
803
0
            Py_DECREF(outf);
804
0
            return NULL;
805
0
        }
806
0
    }
807
0
    if (PyFile_WriteObject(_Py_LATIN1_CHR('\n'), outf, Py_PRINT_RAW) != 0) {
808
0
        Py_DECREF(outf);
809
0
        return NULL;
810
0
    }
811
0
    Py_DECREF(outf);
812
0
    if (PyObject_SetAttr(builtins, _Py_LATIN1_CHR('_'), o) != 0) {
813
0
        return NULL;
814
0
    }
815
0
    Py_RETURN_NONE;
816
0
}
817
818
819
/*[clinic input]
820
sys.excepthook
821
822
    exctype:   object
823
    value:     object
824
    traceback: object
825
    /
826
827
Handle an exception by displaying it with a traceback on sys.stderr.
828
[clinic start generated code]*/
829
830
static PyObject *
831
sys_excepthook_impl(PyObject *module, PyObject *exctype, PyObject *value,
832
                    PyObject *traceback)
833
/*[clinic end generated code: output=18d99fdda21b6b5e input=ecf606fa826f19d9]*/
834
0
{
835
0
    PyErr_Display(NULL, value, traceback);
836
0
    Py_RETURN_NONE;
837
0
}
838
839
840
/*[clinic input]
841
sys.exception
842
843
Return the current exception.
844
845
Return the most recent exception caught by an except clause
846
in the current stack frame or in an older stack frame, or None
847
if no such exception exists.
848
[clinic start generated code]*/
849
850
static PyObject *
851
sys_exception_impl(PyObject *module)
852
/*[clinic end generated code: output=2381ee2f25953e40 input=c88fbb94b6287431]*/
853
0
{
854
0
    _PyErr_StackItem *err_info = _PyErr_GetTopmostException(_PyThreadState_GET());
855
0
    if (err_info->exc_value != NULL) {
856
0
        return Py_NewRef(err_info->exc_value);
857
0
    }
858
0
    Py_RETURN_NONE;
859
0
}
860
861
862
/*[clinic input]
863
sys.exc_info
864
865
Return current exception information: (type, value, traceback).
866
867
Return information about the most recent exception caught by an except
868
clause in the current stack frame or in an older stack frame.
869
[clinic start generated code]*/
870
871
static PyObject *
872
sys_exc_info_impl(PyObject *module)
873
/*[clinic end generated code: output=3afd0940cf3a4d30 input=b5c5bf077788a3e5]*/
874
0
{
875
0
    _PyErr_StackItem *err_info = _PyErr_GetTopmostException(_PyThreadState_GET());
876
0
    return _PyErr_StackItemToExcInfoTuple(err_info);
877
0
}
878
879
880
/*[clinic input]
881
sys.unraisablehook
882
883
    unraisable: object
884
    /
885
886
Handle an unraisable exception.
887
888
The unraisable argument has the following attributes:
889
890
* exc_type: Exception type.
891
* exc_value: Exception value, can be None.
892
* exc_traceback: Exception traceback, can be None.
893
* err_msg: Error message, can be None.
894
* object: Object causing the exception, can be None.
895
[clinic start generated code]*/
896
897
static PyObject *
898
sys_unraisablehook(PyObject *module, PyObject *unraisable)
899
/*[clinic end generated code: output=bb92838b32abaa14 input=ec3af148294af8d3]*/
900
0
{
901
0
    return _PyErr_WriteUnraisableDefaultHook(unraisable);
902
0
}
903
904
905
/*[clinic input]
906
sys.exit
907
908
    status: object = None
909
    /
910
911
Exit the interpreter by raising SystemExit(status).
912
913
If the status is omitted or None, it defaults to zero (i.e., success).
914
If the status is an integer, it will be used as the system exit status.
915
If it is another kind of object, it will be printed and the system
916
exit status will be one (i.e., failure).
917
[clinic start generated code]*/
918
919
static PyObject *
920
sys_exit_impl(PyObject *module, PyObject *status)
921
/*[clinic end generated code: output=13870986c1ab2ec0 input=b86ca9497baa94f2]*/
922
0
{
923
    /* Raise SystemExit so callers may catch it or clean up. */
924
0
    PyErr_SetObject(PyExc_SystemExit, status);
925
0
    return NULL;
926
0
}
927
928
929
static PyObject *
930
get_utf8_unicode(void)
931
78
{
932
78
    _Py_DECLARE_STR(utf_8, "utf-8");
933
78
    PyObject *ret = &_Py_STR(utf_8);
934
78
    return Py_NewRef(ret);
935
78
}
936
937
/*[clinic input]
938
sys.getdefaultencoding
939
940
Return the current default encoding used by the Unicode implementation.
941
[clinic start generated code]*/
942
943
static PyObject *
944
sys_getdefaultencoding_impl(PyObject *module)
945
/*[clinic end generated code: output=256d19dfcc0711e6 input=d416856ddbef6909]*/
946
0
{
947
0
    return get_utf8_unicode();
948
0
}
949
950
/*[clinic input]
951
sys.getfilesystemencoding
952
953
Return the encoding used to convert Unicode filenames to OS filenames.
954
[clinic start generated code]*/
955
956
static PyObject *
957
sys_getfilesystemencoding_impl(PyObject *module)
958
/*[clinic end generated code: output=1dc4bdbe9be44aa7 input=8475f8649b8c7d8c]*/
959
78
{
960
78
    PyInterpreterState *interp = _PyInterpreterState_GET();
961
78
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);
962
963
78
    if (wcscmp(config->filesystem_encoding, L"utf-8") == 0) {
964
78
        return get_utf8_unicode();
965
78
    }
966
967
0
    PyObject *u = PyUnicode_FromWideChar(config->filesystem_encoding, -1);
968
0
    if (u == NULL) {
969
0
        return NULL;
970
0
    }
971
0
    _PyUnicode_InternImmortal(interp, &u);
972
0
    return u;
973
0
}
974
975
/*[clinic input]
976
sys.getfilesystemencodeerrors
977
978
Return the error mode used Unicode to OS filename conversion.
979
[clinic start generated code]*/
980
981
static PyObject *
982
sys_getfilesystemencodeerrors_impl(PyObject *module)
983
/*[clinic end generated code: output=ba77b36bbf7c96f5 input=22a1e8365566f1e5]*/
984
37
{
985
37
    PyInterpreterState *interp = _PyInterpreterState_GET();
986
37
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);
987
37
    PyObject *u = PyUnicode_FromWideChar(config->filesystem_errors, -1);
988
37
    if (u == NULL) {
989
0
        return NULL;
990
0
    }
991
37
    _PyUnicode_InternImmortal(interp, &u);
992
37
    return u;
993
37
}
994
995
/*[clinic input]
996
sys.intern
997
998
    string as s: unicode
999
    /
1000
1001
``Intern'' the given string.
1002
1003
This enters the string in the (global) table of interned strings whose
1004
purpose is to speed up dictionary lookups. Return the string itself or
1005
the previously interned string object with the same value.
1006
[clinic start generated code]*/
1007
1008
static PyObject *
1009
sys_intern_impl(PyObject *module, PyObject *s)
1010
/*[clinic end generated code: output=be680c24f5c9e5d6 input=849483c006924e2f]*/
1011
1.87k
{
1012
1.87k
    if (PyUnicode_CheckExact(s)) {
1013
1.87k
        PyInterpreterState *interp = _PyInterpreterState_GET();
1014
1.87k
        Py_INCREF(s);
1015
1.87k
        _PyUnicode_InternMortal(interp, &s);
1016
1.87k
        return s;
1017
1.87k
    }
1018
0
    else {
1019
0
        PyErr_Format(PyExc_TypeError,
1020
0
                     "can't intern %.400s", Py_TYPE(s)->tp_name);
1021
0
        return NULL;
1022
0
    }
1023
1.87k
}
1024
1025
1026
/*[clinic input]
1027
sys._is_interned -> bool
1028
1029
  string: unicode
1030
  /
1031
1032
Return True if the given string is "interned".
1033
[clinic start generated code]*/
1034
1035
static int
1036
sys__is_interned_impl(PyObject *module, PyObject *string)
1037
/*[clinic end generated code: output=c3678267b4e9d7ed input=039843e17883b606]*/
1038
0
{
1039
0
    return PyUnicode_CHECK_INTERNED(string);
1040
0
}
1041
1042
/*[clinic input]
1043
sys._is_immortal -> bool
1044
1045
  op: object
1046
  /
1047
1048
Return True if the given object is "immortal" per PEP 683.
1049
1050
This function should be used for specialized purposes only.
1051
[clinic start generated code]*/
1052
1053
static int
1054
sys__is_immortal_impl(PyObject *module, PyObject *op)
1055
/*[clinic end generated code: output=c2f5d6a80efb8d1a input=4609c9bf5481db76]*/
1056
0
{
1057
0
    return PyUnstable_IsImmortal(op);
1058
0
}
1059
1060
/*
1061
 * Cached interned string objects used for calling the profile and
1062
 * trace functions.
1063
 */
1064
static PyObject *whatstrings[8] = {
1065
   &_Py_ID(call),
1066
   &_Py_ID(exception),
1067
   &_Py_ID(line),
1068
   &_Py_ID(return),
1069
   &_Py_ID(c_call),
1070
   &_Py_ID(c_exception),
1071
   &_Py_ID(c_return),
1072
   &_Py_ID(opcode),
1073
};
1074
1075
1076
static PyObject *
1077
call_trampoline(PyThreadState *tstate, PyObject* callback,
1078
                PyFrameObject *frame, int what, PyObject *arg)
1079
0
{
1080
    /* call the Python-level function */
1081
0
    if (arg == NULL) {
1082
0
        arg = Py_None;
1083
0
    }
1084
0
    PyObject *args[3] = {(PyObject *)frame, whatstrings[what], arg};
1085
0
    PyObject *result = _PyObject_VectorcallTstate(tstate, callback, args, 3, NULL);
1086
1087
0
    return result;
1088
0
}
1089
1090
static int
1091
profile_trampoline(PyObject *self, PyFrameObject *frame,
1092
                   int what, PyObject *arg)
1093
0
{
1094
0
    PyThreadState *tstate = _PyThreadState_GET();
1095
0
    PyObject *result = call_trampoline(tstate, self, frame, what, arg);
1096
0
    if (result == NULL) {
1097
0
        _PyEval_SetProfile(tstate, NULL, NULL);
1098
0
        return -1;
1099
0
    }
1100
1101
0
    Py_DECREF(result);
1102
0
    return 0;
1103
0
}
1104
1105
static int
1106
trace_trampoline(PyObject *self, PyFrameObject *frame,
1107
                 int what, PyObject *arg)
1108
0
{
1109
0
    PyObject *callback;
1110
0
    if (what == PyTrace_CALL) {
1111
0
        callback = self;
1112
0
    }
1113
0
    else {
1114
0
        callback = frame->f_trace;
1115
0
    }
1116
0
    if (callback == NULL) {
1117
0
        return 0;
1118
0
    }
1119
1120
0
    PyThreadState *tstate = _PyThreadState_GET();
1121
0
    PyObject *result = call_trampoline(tstate, callback, frame, what, arg);
1122
0
    if (result == NULL) {
1123
0
        _PyEval_SetTrace(tstate, NULL, NULL);
1124
0
        Py_CLEAR(frame->f_trace);
1125
0
        return -1;
1126
0
    }
1127
1128
0
    if (result != Py_None) {
1129
0
        Py_XSETREF(frame->f_trace, result);
1130
0
    }
1131
0
    else {
1132
0
        Py_DECREF(result);
1133
0
    }
1134
0
    return 0;
1135
0
}
1136
1137
/*[clinic input]
1138
sys.settrace
1139
1140
    function: object
1141
    /
1142
1143
Set the global debug tracing function.
1144
1145
It will be called on each function call.  See the debugger chapter
1146
in the library manual.
1147
[clinic start generated code]*/
1148
1149
static PyObject *
1150
sys_settrace(PyObject *module, PyObject *function)
1151
/*[clinic end generated code: output=999d12e9d6ec4678 input=8107feb01c5f1c4e]*/
1152
0
{
1153
0
    PyThreadState *tstate = _PyThreadState_GET();
1154
0
    if (function == Py_None) {
1155
0
        if (_PyEval_SetTrace(tstate, NULL, NULL) < 0) {
1156
0
            return NULL;
1157
0
        }
1158
0
    }
1159
0
    else {
1160
0
        if (_PyEval_SetTrace(tstate, trace_trampoline, function) < 0) {
1161
0
            return NULL;
1162
0
        }
1163
0
    }
1164
0
    Py_RETURN_NONE;
1165
0
}
1166
1167
/*[clinic input]
1168
@permit_long_summary
1169
sys._settraceallthreads
1170
1171
    function as arg: object
1172
    /
1173
1174
Set the global debug tracing function in all running threads belonging to the current interpreter.
1175
1176
It will be called on each function call. See the debugger chapter
1177
in the library manual.
1178
[clinic start generated code]*/
1179
1180
static PyObject *
1181
sys__settraceallthreads(PyObject *module, PyObject *arg)
1182
/*[clinic end generated code: output=161cca30207bf3ca input=e5750f5dc01142eb]*/
1183
0
{
1184
0
    PyObject* argument = NULL;
1185
0
    Py_tracefunc func = NULL;
1186
1187
0
    if (arg != Py_None) {
1188
0
        func = trace_trampoline;
1189
0
        argument = arg;
1190
0
    }
1191
1192
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
1193
0
    if (_PyEval_SetTraceAllThreads(interp, func, argument) < 0) {
1194
0
        return NULL;
1195
0
    }
1196
0
    Py_RETURN_NONE;
1197
0
}
1198
1199
/*[clinic input]
1200
sys.gettrace
1201
1202
Return the global debug tracing function set with sys.settrace.
1203
1204
See the debugger chapter in the library manual.
1205
[clinic start generated code]*/
1206
1207
static PyObject *
1208
sys_gettrace_impl(PyObject *module)
1209
/*[clinic end generated code: output=e97e3a4d8c971b6e input=373b51bb2147f4d8]*/
1210
0
{
1211
0
    PyThreadState *tstate = _PyThreadState_GET();
1212
0
    PyObject *temp = tstate->c_traceobj;
1213
1214
0
    if (temp == NULL)
1215
0
        temp = Py_None;
1216
0
    return Py_NewRef(temp);
1217
0
}
1218
1219
/*[clinic input]
1220
sys.setprofile
1221
1222
    function: object
1223
    /
1224
1225
Set the profiling function.
1226
1227
It will be called on each function call and return.  See the profiler
1228
chapter in the library manual.
1229
[clinic start generated code]*/
1230
1231
static PyObject *
1232
sys_setprofile(PyObject *module, PyObject *function)
1233
/*[clinic end generated code: output=1c3503105939db9c input=055d0d7961413a62]*/
1234
0
{
1235
0
    PyThreadState *tstate = _PyThreadState_GET();
1236
0
    if (function == Py_None) {
1237
0
        if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) {
1238
0
            return NULL;
1239
0
        }
1240
0
    }
1241
0
    else {
1242
0
        if (_PyEval_SetProfile(tstate, profile_trampoline, function) < 0) {
1243
0
            return NULL;
1244
0
        }
1245
0
    }
1246
0
    Py_RETURN_NONE;
1247
0
}
1248
1249
/*[clinic input]
1250
@permit_long_summary
1251
sys._setprofileallthreads
1252
1253
    function as arg: object
1254
    /
1255
1256
Set the profiling function in all running threads belonging to the current interpreter.
1257
1258
It will be called on each function call and return.  See the profiler
1259
chapter in the library manual.
1260
[clinic start generated code]*/
1261
1262
static PyObject *
1263
sys__setprofileallthreads(PyObject *module, PyObject *arg)
1264
/*[clinic end generated code: output=2d61319e27b309fe input=9a3dc3352c63b471]*/
1265
0
{
1266
0
    PyObject* argument = NULL;
1267
0
    Py_tracefunc func = NULL;
1268
1269
0
    if (arg != Py_None) {
1270
0
        func = profile_trampoline;
1271
0
        argument = arg;
1272
0
    }
1273
1274
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
1275
0
    if (_PyEval_SetProfileAllThreads(interp, func, argument) < 0) {
1276
0
        return NULL;
1277
0
    }
1278
0
    Py_RETURN_NONE;
1279
0
}
1280
1281
/*[clinic input]
1282
sys.getprofile
1283
1284
Return the profiling function set with sys.setprofile.
1285
1286
See the profiler chapter in the library manual.
1287
[clinic start generated code]*/
1288
1289
static PyObject *
1290
sys_getprofile_impl(PyObject *module)
1291
/*[clinic end generated code: output=579b96b373448188 input=1b3209d89a32965d]*/
1292
0
{
1293
0
    PyThreadState *tstate = _PyThreadState_GET();
1294
0
    PyObject *temp = tstate->c_profileobj;
1295
1296
0
    if (temp == NULL)
1297
0
        temp = Py_None;
1298
0
    return Py_NewRef(temp);
1299
0
}
1300
1301
1302
/*[clinic input]
1303
sys.setswitchinterval
1304
1305
    interval: double
1306
    /
1307
1308
Set the ideal thread switching delay inside the Python interpreter.
1309
1310
The actual frequency of switching threads can be lower if the
1311
interpreter executes long sequences of uninterruptible code
1312
(this is implementation-specific and workload-dependent).
1313
1314
The parameter must represent the desired switching delay in seconds
1315
A typical value is 0.005 (5 milliseconds).
1316
[clinic start generated code]*/
1317
1318
static PyObject *
1319
sys_setswitchinterval_impl(PyObject *module, double interval)
1320
/*[clinic end generated code: output=65a19629e5153983 input=561b477134df91d9]*/
1321
0
{
1322
0
    if (interval <= 0.0) {
1323
0
        PyErr_SetString(PyExc_ValueError,
1324
0
                        "switch interval must be strictly positive");
1325
0
        return NULL;
1326
0
    }
1327
0
    _PyEval_SetSwitchInterval((unsigned long) (1e6 * interval));
1328
0
    Py_RETURN_NONE;
1329
0
}
1330
1331
1332
/*[clinic input]
1333
sys.getswitchinterval -> double
1334
1335
Return the current thread switch interval; see sys.setswitchinterval().
1336
[clinic start generated code]*/
1337
1338
static double
1339
sys_getswitchinterval_impl(PyObject *module)
1340
/*[clinic end generated code: output=a38c277c85b5096d input=bdf9d39c0ebbbb6f]*/
1341
0
{
1342
0
    return 1e-6 * _PyEval_GetSwitchInterval();
1343
0
}
1344
1345
/*[clinic input]
1346
sys.setrecursionlimit
1347
1348
    limit as new_limit: int
1349
    /
1350
1351
Set the maximum depth of the Python interpreter stack to n.
1352
1353
This limit prevents infinite recursion from causing an overflow of the C
1354
stack and crashing Python.  The highest possible limit is platform-
1355
dependent.
1356
[clinic start generated code]*/
1357
1358
static PyObject *
1359
sys_setrecursionlimit_impl(PyObject *module, int new_limit)
1360
/*[clinic end generated code: output=35e1c64754800ace input=b0f7a23393924af3]*/
1361
382
{
1362
382
    PyThreadState *tstate = _PyThreadState_GET();
1363
1364
382
    if (new_limit < 1) {
1365
0
        _PyErr_SetString(tstate, PyExc_ValueError,
1366
0
                         "recursion limit must be greater or equal than 1");
1367
0
        return NULL;
1368
0
    }
1369
1370
    /* Reject too low new limit if the current recursion depth is higher than
1371
       the new low-water mark. */
1372
382
    int depth = tstate->py_recursion_limit - tstate->py_recursion_remaining;
1373
382
    if (depth >= new_limit) {
1374
0
        _PyErr_Format(tstate, PyExc_RecursionError,
1375
0
                      "cannot set the recursion limit to %i at "
1376
0
                      "the recursion depth %i: the limit is too low",
1377
0
                      new_limit, depth);
1378
0
        return NULL;
1379
0
    }
1380
1381
382
    Py_SetRecursionLimit(new_limit);
1382
382
    Py_RETURN_NONE;
1383
382
}
1384
1385
/*[clinic input]
1386
sys.set_coroutine_origin_tracking_depth
1387
1388
  depth: int
1389
1390
Enable or disable origin tracking for coroutine objects in this thread.
1391
1392
Coroutine objects will track 'depth' frames of traceback information
1393
about where they came from, available in their cr_origin attribute.
1394
1395
Set a depth of 0 to disable.
1396
[clinic start generated code]*/
1397
1398
static PyObject *
1399
sys_set_coroutine_origin_tracking_depth_impl(PyObject *module, int depth)
1400
/*[clinic end generated code: output=0a2123c1cc6759c5 input=a1d0a05f89d2c426]*/
1401
0
{
1402
0
    if (_PyEval_SetCoroutineOriginTrackingDepth(depth) < 0) {
1403
0
        return NULL;
1404
0
    }
1405
0
    Py_RETURN_NONE;
1406
0
}
1407
1408
/*[clinic input]
1409
sys.get_coroutine_origin_tracking_depth -> int
1410
1411
Check status of origin tracking for coroutine objects in this thread.
1412
[clinic start generated code]*/
1413
1414
static int
1415
sys_get_coroutine_origin_tracking_depth_impl(PyObject *module)
1416
/*[clinic end generated code: output=3699f7be95a3afb8 input=335266a71205b61a]*/
1417
0
{
1418
0
    return _PyEval_GetCoroutineOriginTrackingDepth();
1419
0
}
1420
1421
static PyTypeObject AsyncGenHooksType;
1422
1423
PyDoc_STRVAR(asyncgen_hooks_doc,
1424
"asyncgen_hooks\n\
1425
\n\
1426
A named tuple providing information about asynchronous\n\
1427
generators hooks.  The attributes are read only.");
1428
1429
static PyStructSequence_Field asyncgen_hooks_fields[] = {
1430
    {"firstiter", "Hook to intercept first iteration"},
1431
    {"finalizer", "Hook to intercept finalization"},
1432
    {0}
1433
};
1434
1435
static PyStructSequence_Desc asyncgen_hooks_desc = {
1436
    "asyncgen_hooks",          /* name */
1437
    asyncgen_hooks_doc,        /* doc */
1438
    asyncgen_hooks_fields ,    /* fields */
1439
    2
1440
};
1441
1442
/*[clinic input]
1443
sys.set_asyncgen_hooks
1444
1445
    firstiter: object = NULL
1446
    finalizer: object = NULL
1447
1448
Set a finalizer for async generators objects.
1449
[clinic start generated code]*/
1450
1451
static PyObject *
1452
sys_set_asyncgen_hooks_impl(PyObject *module, PyObject *firstiter,
1453
                            PyObject *finalizer)
1454
/*[clinic end generated code: output=6fe3b2dd3f9a9db5 input=ef6a1e96361234be]*/
1455
0
{
1456
0
    if (finalizer && finalizer != Py_None) {
1457
0
        if (!PyCallable_Check(finalizer)) {
1458
0
            PyErr_Format(PyExc_TypeError,
1459
0
                         "callable finalizer expected, got %.50s",
1460
0
                         Py_TYPE(finalizer)->tp_name);
1461
0
            return NULL;
1462
0
        }
1463
0
    }
1464
1465
0
    if (firstiter && firstiter != Py_None) {
1466
0
        if (!PyCallable_Check(firstiter)) {
1467
0
            PyErr_Format(PyExc_TypeError,
1468
0
                         "callable firstiter expected, got %.50s",
1469
0
                         Py_TYPE(firstiter)->tp_name);
1470
0
            return NULL;
1471
0
        }
1472
0
    }
1473
1474
0
    PyObject *cur_finalizer = _PyEval_GetAsyncGenFinalizer();
1475
1476
0
    if (finalizer && finalizer != Py_None) {
1477
0
        if (_PyEval_SetAsyncGenFinalizer(finalizer) < 0) {
1478
0
            return NULL;
1479
0
        }
1480
0
    }
1481
0
    else if (finalizer == Py_None && _PyEval_SetAsyncGenFinalizer(NULL) < 0) {
1482
0
        return NULL;
1483
0
    }
1484
1485
0
    if (firstiter && firstiter != Py_None) {
1486
0
        if (_PyEval_SetAsyncGenFirstiter(firstiter) < 0) {
1487
0
            goto error;
1488
0
        }
1489
0
    }
1490
0
    else if (firstiter == Py_None && _PyEval_SetAsyncGenFirstiter(NULL) < 0) {
1491
0
        goto error;
1492
0
    }
1493
1494
0
    Py_RETURN_NONE;
1495
1496
0
error:
1497
0
    _PyEval_SetAsyncGenFinalizer(cur_finalizer);
1498
0
    return NULL;
1499
0
}
1500
1501
/*[clinic input]
1502
sys.get_asyncgen_hooks
1503
1504
Return the installed asynchronous generators hooks.
1505
1506
This returns a namedtuple of the form (firstiter, finalizer).
1507
[clinic start generated code]*/
1508
1509
static PyObject *
1510
sys_get_asyncgen_hooks_impl(PyObject *module)
1511
/*[clinic end generated code: output=53a253707146f6cf input=3676b9ea62b14625]*/
1512
0
{
1513
0
    PyObject *res;
1514
0
    PyObject *firstiter = _PyEval_GetAsyncGenFirstiter();
1515
0
    PyObject *finalizer = _PyEval_GetAsyncGenFinalizer();
1516
1517
0
    res = PyStructSequence_New(&AsyncGenHooksType);
1518
0
    if (res == NULL) {
1519
0
        return NULL;
1520
0
    }
1521
1522
0
    if (firstiter == NULL) {
1523
0
        firstiter = Py_None;
1524
0
    }
1525
1526
0
    if (finalizer == NULL) {
1527
0
        finalizer = Py_None;
1528
0
    }
1529
1530
0
    PyStructSequence_SET_ITEM(res, 0, Py_NewRef(firstiter));
1531
0
    PyStructSequence_SET_ITEM(res, 1, Py_NewRef(finalizer));
1532
1533
0
    return res;
1534
0
}
1535
1536
1537
static PyTypeObject Hash_InfoType;
1538
1539
PyDoc_STRVAR(hash_info_doc,
1540
"hash_info\n\
1541
\n\
1542
A named tuple providing parameters used for computing\n\
1543
hashes. The attributes are read only.");
1544
1545
static PyStructSequence_Field hash_info_fields[] = {
1546
    {"width", "width of the type used for hashing, in bits"},
1547
    {"modulus", "prime number giving the modulus on which the hash "
1548
                "function is based"},
1549
    {"inf", "value to be used for hash of a positive infinity"},
1550
    {"nan", "value to be used for hash of a nan"},
1551
    {"imag", "multiplier used for the imaginary part of a complex number"},
1552
    {"algorithm", "name of the algorithm for hashing of str, bytes and "
1553
                  "memoryviews"},
1554
    {"hash_bits", "internal output size of hash algorithm"},
1555
    {"seed_bits", "seed size of hash algorithm"},
1556
    {"cutoff", "small string optimization cutoff"},
1557
    {NULL, NULL}
1558
};
1559
1560
static PyStructSequence_Desc hash_info_desc = {
1561
    "sys.hash_info",
1562
    hash_info_doc,
1563
    hash_info_fields,
1564
    9,
1565
};
1566
1567
static PyObject *
1568
get_hash_info(PyThreadState *tstate)
1569
37
{
1570
37
    PyObject *hash_info;
1571
37
    int field = 0;
1572
37
    PyHash_FuncDef *hashfunc;
1573
37
    hash_info = PyStructSequence_New(&Hash_InfoType);
1574
37
    if (hash_info == NULL) {
1575
0
        return NULL;
1576
0
    }
1577
37
    hashfunc = PyHash_GetFuncDef();
1578
1579
37
#define SET_HASH_INFO_ITEM(CALL)                             \
1580
333
    do {                                                     \
1581
333
        PyObject *item = (CALL);                             \
1582
333
        if (item == NULL) {                                  \
1583
0
            Py_CLEAR(hash_info);                             \
1584
0
            return NULL;                                     \
1585
0
        }                                                    \
1586
333
        PyStructSequence_SET_ITEM(hash_info, field++, item); \
1587
333
    } while(0)
1588
1589
37
    SET_HASH_INFO_ITEM(PyLong_FromLong(8 * sizeof(Py_hash_t)));
1590
37
    SET_HASH_INFO_ITEM(PyLong_FromSsize_t(PyHASH_MODULUS));
1591
37
    SET_HASH_INFO_ITEM(PyLong_FromLong(PyHASH_INF));
1592
37
    SET_HASH_INFO_ITEM(PyLong_FromLong(0));  // This is no longer used
1593
37
    SET_HASH_INFO_ITEM(PyLong_FromLong(PyHASH_IMAG));
1594
37
    SET_HASH_INFO_ITEM(PyUnicode_FromString(hashfunc->name));
1595
37
    SET_HASH_INFO_ITEM(PyLong_FromLong(hashfunc->hash_bits));
1596
37
    SET_HASH_INFO_ITEM(PyLong_FromLong(hashfunc->seed_bits));
1597
37
    SET_HASH_INFO_ITEM(PyLong_FromLong(Py_HASH_CUTOFF));
1598
1599
37
#undef SET_HASH_INFO_ITEM
1600
1601
37
    return hash_info;
1602
37
}
1603
/*[clinic input]
1604
sys.getrecursionlimit
1605
1606
Return the current value of the recursion limit.
1607
1608
The recursion limit is the maximum depth of the Python interpreter
1609
stack.  This limit prevents infinite recursion from causing an overflow
1610
of the C stack and crashing Python.
1611
[clinic start generated code]*/
1612
1613
static PyObject *
1614
sys_getrecursionlimit_impl(PyObject *module)
1615
/*[clinic end generated code: output=d571fb6b4549ef2e input=1c6129fd2efaeea8]*/
1616
733
{
1617
733
    return PyLong_FromLong(Py_GetRecursionLimit());
1618
733
}
1619
1620
#ifdef MS_WINDOWS
1621
1622
static PyTypeObject WindowsVersionType = { 0 };
1623
1624
static PyStructSequence_Field windows_version_fields[] = {
1625
    {"major", "Major version number"},
1626
    {"minor", "Minor version number"},
1627
    {"build", "Build number"},
1628
    {"platform", "Operating system platform"},
1629
    {"service_pack", "Latest Service Pack installed on the system"},
1630
    {"service_pack_major", "Service Pack major version number"},
1631
    {"service_pack_minor", "Service Pack minor version number"},
1632
    {"suite_mask", "Bit mask identifying available product suites"},
1633
    {"product_type", "System product type"},
1634
    {"platform_version", "Diagnostic version number"},
1635
    {"device_family", "'Desktop', 'Xbox' or 'UWP'"},
1636
    {0}
1637
};
1638
1639
static PyStructSequence_Desc windows_version_desc = {
1640
    "sys.getwindowsversion",       /* name */
1641
    sys_getwindowsversion__doc__,  /* doc */
1642
    windows_version_fields,        /* fields */
1643
    5                              /* For backward compatibility,
1644
                                      only the first 5 items are accessible
1645
                                      via indexing, the rest are name only */
1646
};
1647
1648
#ifdef MS_WINDOWS_DESKTOP
1649
static PyObject *
1650
_sys_getwindowsversion_from_kernel32(void)
1651
{
1652
    HANDLE hKernel32;
1653
    wchar_t kernel32_path[MAX_PATH];
1654
    LPVOID verblock;
1655
    DWORD verblock_size;
1656
    VS_FIXEDFILEINFO *ffi;
1657
    UINT ffi_len;
1658
    DWORD realMajor, realMinor, realBuild;
1659
1660
    Py_BEGIN_ALLOW_THREADS
1661
    hKernel32 = GetModuleHandleW(L"kernel32.dll");
1662
    Py_END_ALLOW_THREADS
1663
    if (!hKernel32 || !GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH)) {
1664
        PyErr_SetFromWindowsErr(0);
1665
        return NULL;
1666
    }
1667
    verblock_size = GetFileVersionInfoSizeW(kernel32_path, NULL);
1668
    if (!verblock_size) {
1669
        PyErr_SetFromWindowsErr(0);
1670
        return NULL;
1671
    }
1672
    verblock = PyMem_RawMalloc(verblock_size);
1673
    if (!verblock ||
1674
        !GetFileVersionInfoW(kernel32_path, 0, verblock_size, verblock) ||
1675
        !VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) {
1676
        PyErr_SetFromWindowsErr(0);
1677
        if (verblock) {
1678
            PyMem_RawFree(verblock);
1679
        }
1680
        return NULL;
1681
    }
1682
1683
    realMajor = HIWORD(ffi->dwProductVersionMS);
1684
    realMinor = LOWORD(ffi->dwProductVersionMS);
1685
    realBuild = HIWORD(ffi->dwProductVersionLS);
1686
    PyMem_RawFree(verblock);
1687
    return Py_BuildValue("(kkk)", realMajor, realMinor, realBuild);
1688
}
1689
#endif /* MS_WINDOWS_DESKTOP */
1690
1691
/* Disable deprecation warnings about GetVersionEx as the result is
1692
   being passed straight through to the caller, who is responsible for
1693
   using it correctly. */
1694
#pragma warning(push)
1695
#pragma warning(disable:4996)
1696
1697
/*[clinic input]
1698
sys.getwindowsversion
1699
1700
Return info about the running version of Windows as a named tuple.
1701
1702
The members are named: major, minor, build, platform, service_pack,
1703
service_pack_major, service_pack_minor, suite_mask, product_type and
1704
platform_version. For backward compatibility, only the first 5 items
1705
are available by indexing. All elements are numbers, except
1706
service_pack and platform_type which are strings, and platform_version
1707
which is a 3-tuple. Platform is always 2. Product_type may be 1 for a
1708
workstation, 2 for a domain controller, 3 for a server.
1709
Platform_version is a 3-tuple containing a version number that is
1710
intended for identifying the OS rather than feature detection.
1711
[clinic start generated code]*/
1712
1713
static PyObject *
1714
sys_getwindowsversion_impl(PyObject *module)
1715
/*[clinic end generated code: output=1ec063280b932857 input=73a228a328fee63a]*/
1716
{
1717
    PyObject *version;
1718
    int pos = 0;
1719
1720
    if (PyObject_GetOptionalAttrString(module, "_cached_windows_version", &version) < 0) {
1721
        return NULL;
1722
    };
1723
    if (version && PyObject_TypeCheck(version, &WindowsVersionType)) {
1724
        return version;
1725
    }
1726
    Py_XDECREF(version);
1727
1728
    OSVERSIONINFOEXW ver;
1729
    ZeroMemory(&ver, sizeof(ver));
1730
    ver.dwOSVersionInfoSize = sizeof(ver);
1731
    if (!GetVersionExW((OSVERSIONINFOW*) &ver))
1732
        return PyErr_SetFromWindowsErr(0);
1733
1734
    version = PyStructSequence_New(&WindowsVersionType);
1735
    if (version == NULL)
1736
        return NULL;
1737
1738
#define SET_VERSION_INFO(CALL)                               \
1739
    do {                                                     \
1740
        PyObject *item = (CALL);                             \
1741
        if (item == NULL) {                                  \
1742
            goto error;                                      \
1743
        }                                                    \
1744
        PyStructSequence_SET_ITEM(version, pos++, item);     \
1745
    } while(0)
1746
1747
    SET_VERSION_INFO(PyLong_FromLong(ver.dwMajorVersion));
1748
    SET_VERSION_INFO(PyLong_FromLong(ver.dwMinorVersion));
1749
    SET_VERSION_INFO(PyLong_FromLong(ver.dwBuildNumber));
1750
    SET_VERSION_INFO(PyLong_FromLong(ver.dwPlatformId));
1751
    SET_VERSION_INFO(PyUnicode_FromWideChar(ver.szCSDVersion, -1));
1752
    SET_VERSION_INFO(PyLong_FromLong(ver.wServicePackMajor));
1753
    SET_VERSION_INFO(PyLong_FromLong(ver.wServicePackMinor));
1754
    SET_VERSION_INFO(PyLong_FromLong(ver.wSuiteMask));
1755
    SET_VERSION_INFO(PyLong_FromLong(ver.wProductType));
1756
1757
#if defined(MS_WINDOWS_DESKTOP)
1758
    // GetVersion will lie if we are running in a compatibility mode.
1759
    // We need to read the version info from a system file resource
1760
    // to accurately identify the OS version. If we fail for any reason,
1761
    // just return whatever GetVersion said.
1762
    PyObject *realVersion = _sys_getwindowsversion_from_kernel32();
1763
    if (!realVersion) {
1764
        if (!PyErr_ExceptionMatches(PyExc_WindowsError)) {
1765
            goto error;
1766
        }
1767
1768
        PyErr_Clear();
1769
        realVersion = Py_BuildValue("(kkk)",
1770
            ver.dwMajorVersion,
1771
            ver.dwMinorVersion,
1772
            ver.dwBuildNumber
1773
        );
1774
    }
1775
1776
    SET_VERSION_INFO(realVersion);
1777
    SET_VERSION_INFO(PyUnicode_FromString("Desktop"));
1778
#elif defined(MS_WINDOWS_GAMES)
1779
    SET_VERSION_INFO(Py_BuildValue("(kkk)", ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber));
1780
    SET_VERSION_INFO(PyUnicode_FromString("Xbox"));
1781
#else
1782
    SET_VERSION_INFO(Py_BuildValue("(kkk)", ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber));
1783
    SET_VERSION_INFO(PyUnicode_FromString("UWP"));
1784
#endif
1785
1786
#undef SET_VERSION_INFO
1787
1788
    if (PyObject_SetAttrString(module, "_cached_windows_version", version) < 0) {
1789
        goto error;
1790
    }
1791
1792
    return version;
1793
1794
error:
1795
    Py_DECREF(version);
1796
    return NULL;
1797
}
1798
1799
#pragma warning(pop)
1800
#endif /* MS_WINDOWS */
1801
1802
#ifdef HAVE_DLOPEN
1803
1804
/*[clinic input]
1805
sys.setdlopenflags
1806
1807
    flags as new_val: int
1808
    /
1809
1810
Set the flags used by the interpreter for dlopen calls.
1811
1812
This is used, for example, when the interpreter loads extension
1813
modules. Among other things, this will enable a lazy resolving of
1814
symbols when importing a module, if called as sys.setdlopenflags(0).
1815
To share symbols across extension modules, call as
1816
sys.setdlopenflags(os.RTLD_GLOBAL).  Symbolic names for the flag
1817
modules can be found in the os module (RTLD_xxx constants, e.g.
1818
os.RTLD_LAZY).
1819
[clinic start generated code]*/
1820
1821
static PyObject *
1822
sys_setdlopenflags_impl(PyObject *module, int new_val)
1823
/*[clinic end generated code: output=ec918b7fe0a37281 input=4c838211e857a77f]*/
1824
0
{
1825
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
1826
0
    _PyImport_SetDLOpenFlags(interp, new_val);
1827
0
    Py_RETURN_NONE;
1828
0
}
1829
1830
1831
/*[clinic input]
1832
sys.getdlopenflags
1833
1834
Return the current value of the flags that are used for dlopen calls.
1835
1836
The flag constants are defined in the os module.
1837
[clinic start generated code]*/
1838
1839
static PyObject *
1840
sys_getdlopenflags_impl(PyObject *module)
1841
/*[clinic end generated code: output=e92cd1bc5005da6e input=dc4ea0899c53b4b6]*/
1842
0
{
1843
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
1844
0
    return PyLong_FromLong(
1845
0
            _PyImport_GetDLOpenFlags(interp));
1846
0
}
1847
1848
#endif  /* HAVE_DLOPEN */
1849
1850
#ifdef USE_MALLOPT
1851
/* Link with -lmalloc (or -lmpc) on an SGI */
1852
#include <malloc.h>
1853
1854
/*[clinic input]
1855
sys.mdebug
1856
1857
    flag: int
1858
    /
1859
[clinic start generated code]*/
1860
1861
static PyObject *
1862
sys_mdebug_impl(PyObject *module, int flag)
1863
/*[clinic end generated code: output=5431d545847c3637 input=151d150ae1636f8a]*/
1864
{
1865
    int flag;
1866
    mallopt(M_DEBUG, flag);
1867
    Py_RETURN_NONE;
1868
}
1869
#endif /* USE_MALLOPT */
1870
1871
1872
/*[clinic input]
1873
@permit_long_summary
1874
sys.get_int_max_str_digits
1875
1876
Return the maximum string digits limit for non-binary int<->str conversions.
1877
[clinic start generated code]*/
1878
1879
static PyObject *
1880
sys_get_int_max_str_digits_impl(PyObject *module)
1881
/*[clinic end generated code: output=0042f5e8ae0e8631 input=77fb74e987ba7ecb]*/
1882
0
{
1883
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
1884
0
    int maxdigits = _Py_atomic_load_int(&interp->long_state.max_str_digits);
1885
0
    return PyLong_FromLong(maxdigits);
1886
0
}
1887
1888
1889
/*[clinic input]
1890
@permit_long_summary
1891
sys.set_int_max_str_digits
1892
1893
    maxdigits: int
1894
1895
Set the maximum string digits limit for non-binary int<->str conversions.
1896
[clinic start generated code]*/
1897
1898
static PyObject *
1899
sys_set_int_max_str_digits_impl(PyObject *module, int maxdigits)
1900
/*[clinic end generated code: output=734d4c2511f2a56d input=d4c0bf50c466d57a]*/
1901
0
{
1902
0
    if (_PySys_SetIntMaxStrDigits(maxdigits) < 0) {
1903
0
        return NULL;
1904
0
    }
1905
0
    Py_RETURN_NONE;
1906
0
}
1907
1908
size_t
1909
_PySys_GetSizeOf(PyObject *o)
1910
0
{
1911
0
    PyObject *res = NULL;
1912
0
    PyObject *method;
1913
0
    Py_ssize_t size;
1914
0
    PyThreadState *tstate = _PyThreadState_GET();
1915
1916
    /* Make sure the type is initialized. float gets initialized late */
1917
0
    if (PyType_Ready(Py_TYPE(o)) < 0) {
1918
0
        return (size_t)-1;
1919
0
    }
1920
1921
0
    method = _PyObject_LookupSpecial(o, &_Py_ID(__sizeof__));
1922
0
    if (method == NULL) {
1923
0
        if (!_PyErr_Occurred(tstate)) {
1924
0
            _PyErr_Format(tstate, PyExc_TypeError,
1925
0
                          "Type %.100s doesn't define __sizeof__",
1926
0
                          Py_TYPE(o)->tp_name);
1927
0
        }
1928
0
    }
1929
0
    else {
1930
0
        res = _PyObject_CallNoArgs(method);
1931
0
        Py_DECREF(method);
1932
0
    }
1933
1934
0
    if (res == NULL)
1935
0
        return (size_t)-1;
1936
1937
0
    size = PyLong_AsSsize_t(res);
1938
0
    Py_DECREF(res);
1939
0
    if (size == -1 && _PyErr_Occurred(tstate))
1940
0
        return (size_t)-1;
1941
1942
0
    if (size < 0) {
1943
0
        _PyErr_SetString(tstate, PyExc_ValueError,
1944
0
                          "__sizeof__() should return >= 0");
1945
0
        return (size_t)-1;
1946
0
    }
1947
1948
0
    size_t presize = 0;
1949
0
    if (!Py_IS_TYPE(o, &PyType_Type) ||
1950
0
         PyType_HasFeature((PyTypeObject *)o, Py_TPFLAGS_HEAPTYPE))
1951
0
    {
1952
        /* Add the size of the pre-header if "o" is not a static type */
1953
0
        presize = _PyType_PreHeaderSize(Py_TYPE(o));
1954
0
    }
1955
1956
0
    return (size_t)size + presize;
1957
0
}
1958
1959
/*[clinic input]
1960
sys.getsizeof
1961
1962
    object as o: object
1963
    default as dflt: object = NULL
1964
1965
Return the size of object in bytes.
1966
[clinic start generated code]*/
1967
1968
static PyObject *
1969
sys_getsizeof_impl(PyObject *module, PyObject *o, PyObject *dflt)
1970
/*[clinic end generated code: output=c9dee8179ae2a973 input=fd71e98f0e3ae131]*/
1971
0
{
1972
0
    size_t size;
1973
0
    PyThreadState *tstate = _PyThreadState_GET();
1974
1975
0
    size = _PySys_GetSizeOf(o);
1976
1977
0
    if (size == (size_t)-1 && _PyErr_Occurred(tstate)) {
1978
        /* Has a default value been given */
1979
0
        if (dflt != NULL && _PyErr_ExceptionMatches(tstate, PyExc_TypeError)) {
1980
0
            _PyErr_Clear(tstate);
1981
0
            return Py_NewRef(dflt);
1982
0
        }
1983
0
        else
1984
0
            return NULL;
1985
0
    }
1986
1987
0
    return PyLong_FromSize_t(size);
1988
0
}
1989
1990
/*[clinic input]
1991
sys.getrefcount -> Py_ssize_t
1992
1993
    object:  object
1994
    /
1995
1996
Return the reference count of object.
1997
1998
The count returned is generally one higher than you might expect,
1999
because it includes the (temporary) reference as an argument to
2000
getrefcount().
2001
[clinic start generated code]*/
2002
2003
static Py_ssize_t
2004
sys_getrefcount_impl(PyObject *module, PyObject *object)
2005
/*[clinic end generated code: output=5fd477f2264b85b2 input=bf474efd50a21535]*/
2006
4
{
2007
4
    return Py_REFCNT(object);
2008
4
}
2009
2010
#ifdef Py_REF_DEBUG
2011
/*[clinic input]
2012
sys.gettotalrefcount -> Py_ssize_t
2013
[clinic start generated code]*/
2014
2015
static Py_ssize_t
2016
sys_gettotalrefcount_impl(PyObject *module)
2017
/*[clinic end generated code: output=4103886cf17c25bc input=53b744faa5d2e4f6]*/
2018
{
2019
    /* It may make sense to return the total for the current interpreter
2020
       or have a second function that does so. */
2021
    return _Py_GetGlobalRefTotal();
2022
}
2023
2024
#endif /* Py_REF_DEBUG */
2025
2026
/*[clinic input]
2027
sys.getallocatedblocks -> Py_ssize_t
2028
2029
Return the number of memory blocks currently allocated.
2030
[clinic start generated code]*/
2031
2032
static Py_ssize_t
2033
sys_getallocatedblocks_impl(PyObject *module)
2034
/*[clinic end generated code: output=f0c4e873f0b6dcf7 input=dab13ee346a0673e]*/
2035
0
{
2036
    // It might make sense to return the count
2037
    // for just the current interpreter.
2038
0
    return _Py_GetGlobalAllocatedBlocks();
2039
0
}
2040
2041
/*[clinic input]
2042
sys.getunicodeinternedsize -> Py_ssize_t
2043
2044
    *
2045
    _only_immortal: bool = False
2046
2047
Return the number of elements of the unicode interned dictionary
2048
[clinic start generated code]*/
2049
2050
static Py_ssize_t
2051
sys_getunicodeinternedsize_impl(PyObject *module, int _only_immortal)
2052
/*[clinic end generated code: output=29a6377a94a14f70 input=0330b3408dd5bcc6]*/
2053
0
{
2054
0
    if (_only_immortal) {
2055
0
        return _PyUnicode_InternedSize_Immortal();
2056
0
    }
2057
0
    else {
2058
0
        return _PyUnicode_InternedSize();
2059
0
    }
2060
0
}
2061
2062
/*[clinic input]
2063
sys._getframe
2064
2065
    depth: int = 0
2066
    /
2067
2068
Return a frame object from the call stack.
2069
2070
If optional integer depth is given, return the frame object that many
2071
calls below the top of the stack.  If that is deeper than the call
2072
stack, ValueError is raised.  The default for depth is zero, returning
2073
the frame at the top of the call stack.
2074
2075
This function should be used for internal and specialized purposes
2076
only.
2077
[clinic start generated code]*/
2078
2079
static PyObject *
2080
sys__getframe_impl(PyObject *module, int depth)
2081
/*[clinic end generated code: output=d438776c04d59804 input=c1be8a6464b11ee5]*/
2082
21.3k
{
2083
21.3k
    PyThreadState *tstate = _PyThreadState_GET();
2084
21.3k
    _PyInterpreterFrame *frame = tstate->current_frame;
2085
2086
21.3k
    if (frame != NULL) {
2087
42.9k
        while (depth > 0) {
2088
21.5k
            frame = _PyFrame_GetFirstComplete(frame->previous);
2089
21.5k
            if (frame == NULL) {
2090
0
                break;
2091
0
            }
2092
21.5k
            --depth;
2093
21.5k
        }
2094
21.3k
    }
2095
21.3k
    if (frame == NULL) {
2096
0
        _PyErr_SetString(tstate, PyExc_ValueError,
2097
0
                         "call stack is not deep enough");
2098
0
        return NULL;
2099
0
    }
2100
2101
21.3k
    PyObject *pyFrame = Py_XNewRef((PyObject *)_PyFrame_GetFrameObject(frame));
2102
21.3k
    if (pyFrame && _PySys_Audit(tstate, "sys._getframe", "(O)", pyFrame) < 0) {
2103
0
        Py_DECREF(pyFrame);
2104
0
        return NULL;
2105
0
    }
2106
21.3k
    return pyFrame;
2107
21.3k
}
2108
2109
/*[clinic input]
2110
@permit_long_summary
2111
sys._current_frames
2112
2113
Return a dict mapping each thread's thread id to its current stack frame.
2114
2115
This function should be used for specialized purposes only.
2116
[clinic start generated code]*/
2117
2118
static PyObject *
2119
sys__current_frames_impl(PyObject *module)
2120
/*[clinic end generated code: output=d2a41ac0a0a3809a input=e1ce34f43501e0d6]*/
2121
0
{
2122
0
    return _PyThread_CurrentFrames();
2123
0
}
2124
2125
/*[clinic input]
2126
@permit_long_summary
2127
sys._current_exceptions
2128
2129
Return a dict mapping each thread's identifier to its current raised exception.
2130
2131
This function should be used for specialized purposes only.
2132
[clinic start generated code]*/
2133
2134
static PyObject *
2135
sys__current_exceptions_impl(PyObject *module)
2136
/*[clinic end generated code: output=2ccfd838c746f0ba input=4ba429b6cfcd736d]*/
2137
0
{
2138
0
    return _PyThread_CurrentExceptions();
2139
0
}
2140
2141
/*[clinic input]
2142
sys.call_tracing
2143
2144
    func: object
2145
    args as funcargs: object(subclass_of='&PyTuple_Type')
2146
    /
2147
2148
Call func(*args), while tracing is enabled.
2149
2150
The tracing state is saved, and restored afterwards.  This is intended
2151
to be called from a debugger from a checkpoint, to recursively debug
2152
some other code.
2153
[clinic start generated code]*/
2154
2155
static PyObject *
2156
sys_call_tracing_impl(PyObject *module, PyObject *func, PyObject *funcargs)
2157
/*[clinic end generated code: output=7e4999853cd4e5a6 input=5102e8b11049f92f]*/
2158
0
{
2159
0
    return _PyEval_CallTracing(func, funcargs);
2160
0
}
2161
2162
/*[clinic input]
2163
sys._debugmallocstats
2164
2165
Print summary info to stderr about the state of pymalloc's structures.
2166
2167
In Py_DEBUG mode, also perform some expensive internal consistency
2168
checks.
2169
[clinic start generated code]*/
2170
2171
static PyObject *
2172
sys__debugmallocstats_impl(PyObject *module)
2173
/*[clinic end generated code: output=ec3565f8c7cee46a input=33c0c9c416f98424]*/
2174
0
{
2175
0
#ifdef WITH_PYMALLOC
2176
0
    if (_PyObject_DebugMallocStats(stderr)) {
2177
0
        fputc('\n', stderr);
2178
0
    }
2179
0
#endif
2180
0
    _PyObject_DebugTypeStats(stderr);
2181
2182
0
    Py_RETURN_NONE;
2183
0
}
2184
2185
#ifdef Py_TRACE_REFS
2186
/* Defined in objects.c because it uses static globals in that file */
2187
extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
2188
#endif
2189
2190
2191
/*[clinic input]
2192
sys._clear_type_cache
2193
2194
Clear the internal type lookup cache.
2195
[clinic start generated code]*/
2196
2197
static PyObject *
2198
sys__clear_type_cache_impl(PyObject *module)
2199
/*[clinic end generated code: output=20e48ca54a6f6971 input=127f3e04a8d9b555]*/
2200
0
{
2201
0
    if (PyErr_WarnEx(PyExc_DeprecationWarning,
2202
0
                     "sys._clear_type_cache() is deprecated and"
2203
0
                     " scheduled for removal in a future version."
2204
0
                     " Use sys._clear_internal_caches() instead.",
2205
0
                     1) < 0)
2206
0
    {
2207
0
        return NULL;
2208
0
    }
2209
0
    PyType_ClearCache();
2210
0
    Py_RETURN_NONE;
2211
0
}
2212
2213
/*[clinic input]
2214
sys._clear_internal_caches
2215
2216
Clear all internal performance-related caches.
2217
[clinic start generated code]*/
2218
2219
static PyObject *
2220
sys__clear_internal_caches_impl(PyObject *module)
2221
/*[clinic end generated code: output=0ee128670a4966d6 input=253e741ca744f6e8]*/
2222
0
{
2223
#ifdef _Py_TIER2
2224
    PyInterpreterState *interp = _PyInterpreterState_GET();
2225
    _Py_Executors_InvalidateAll(interp, 0);
2226
#endif
2227
#ifdef Py_GIL_DISABLED
2228
    if (_Py_ClearUnusedTLBC(_PyInterpreterState_GET()) < 0) {
2229
        return NULL;
2230
    }
2231
#endif
2232
0
    PyType_ClearCache();
2233
0
    Py_RETURN_NONE;
2234
0
}
2235
2236
/* Note that, for now, we do not have a per-interpreter equivalent
2237
  for sys.is_finalizing(). */
2238
2239
/*[clinic input]
2240
sys.is_finalizing
2241
2242
Return True if Python is exiting.
2243
[clinic start generated code]*/
2244
2245
static PyObject *
2246
sys_is_finalizing_impl(PyObject *module)
2247
/*[clinic end generated code: output=735b5ff7962ab281 input=f0df747a039948a5]*/
2248
0
{
2249
0
    return PyBool_FromLong(Py_IsFinalizing());
2250
0
}
2251
2252
2253
#ifdef Py_STATS
2254
/*[clinic input]
2255
sys._stats_on
2256
2257
Turns on stats gathering (stats gathering is off by default).
2258
[clinic start generated code]*/
2259
2260
static PyObject *
2261
sys__stats_on_impl(PyObject *module)
2262
/*[clinic end generated code: output=aca53eafcbb4d9fe input=43b5bfe145299e55]*/
2263
{
2264
    if (_Py_StatsOn() < 0) {
2265
        return NULL;
2266
    }
2267
    Py_RETURN_NONE;
2268
}
2269
2270
/*[clinic input]
2271
sys._stats_off
2272
2273
Turns off stats gathering (stats gathering is off by default).
2274
[clinic start generated code]*/
2275
2276
static PyObject *
2277
sys__stats_off_impl(PyObject *module)
2278
/*[clinic end generated code: output=1534c1ee63812214 input=d1a84c60c56cbce2]*/
2279
{
2280
    _Py_StatsOff();
2281
    Py_RETURN_NONE;
2282
}
2283
2284
/*[clinic input]
2285
sys._stats_clear
2286
2287
Clears the stats.
2288
[clinic start generated code]*/
2289
2290
static PyObject *
2291
sys__stats_clear_impl(PyObject *module)
2292
/*[clinic end generated code: output=fb65a2525ee50604 input=3e03f2654f44da96]*/
2293
{
2294
    _Py_StatsClear();
2295
    Py_RETURN_NONE;
2296
}
2297
2298
/*[clinic input]
2299
sys._stats_dump -> bool
2300
2301
Dump stats to file, and clears the stats.
2302
2303
Return False if no statistics were not dumped because stats gathering
2304
was off.
2305
[clinic start generated code]*/
2306
2307
static int
2308
sys__stats_dump_impl(PyObject *module)
2309
/*[clinic end generated code: output=6e346b4ba0de4489 input=7f3b7758cb59d2ff]*/
2310
{
2311
    int res = _Py_PrintSpecializationStats(1);
2312
    _Py_StatsClear();
2313
    return res;
2314
}
2315
#endif   // Py_STATS
2316
2317
2318
#ifdef ANDROID_API_LEVEL
2319
/*[clinic input]
2320
sys.getandroidapilevel
2321
2322
Return the build time API version of Android as an integer.
2323
[clinic start generated code]*/
2324
2325
static PyObject *
2326
sys_getandroidapilevel_impl(PyObject *module)
2327
/*[clinic end generated code: output=214abf183a1c70c1 input=3e6d6c9fcdd24ac6]*/
2328
{
2329
    return PyLong_FromLong(ANDROID_API_LEVEL);
2330
}
2331
#endif   /* ANDROID_API_LEVEL */
2332
2333
/*[clinic input]
2334
sys.activate_stack_trampoline
2335
2336
    backend: str
2337
    /
2338
2339
Activate stack profiler trampoline *backend*.
2340
[clinic start generated code]*/
2341
2342
static PyObject *
2343
sys_activate_stack_trampoline_impl(PyObject *module, const char *backend)
2344
/*[clinic end generated code: output=5783cdeb51874b43 input=a12df928758a82b4]*/
2345
0
{
2346
0
#ifdef PY_HAVE_PERF_TRAMPOLINE
2347
#ifdef _Py_JIT
2348
    // Perf state is process-wide, and only the main interpreter can enable
2349
    // the JIT. Check it even when called from a subinterpreter (gh-157247).
2350
    if (_PyInterpreterState_Main()->jit) {
2351
        PyErr_SetString(PyExc_ValueError, "Cannot activate the perf trampoline if the JIT is active");
2352
        return NULL;
2353
    }
2354
#endif
2355
2356
0
    if (strcmp(backend, "perf") == 0) {
2357
0
        _PyPerf_Callbacks cur_cb;
2358
0
        _PyPerfTrampoline_GetCallbacks(&cur_cb);
2359
0
        if (cur_cb.write_state != _Py_perfmap_callbacks.write_state) {
2360
0
            if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_callbacks) < 0 ) {
2361
0
                PyErr_SetString(PyExc_ValueError, "can't activate perf trampoline");
2362
0
                return NULL;
2363
0
            }
2364
0
        }
2365
0
    }
2366
0
    else if (strcmp(backend, "perf_jit") == 0) {
2367
0
        _PyPerf_Callbacks cur_cb;
2368
0
        _PyPerfTrampoline_GetCallbacks(&cur_cb);
2369
0
        if (cur_cb.write_state != _Py_perfmap_jit_callbacks.write_state) {
2370
0
            if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_jit_callbacks) < 0 ) {
2371
0
                PyErr_SetString(PyExc_ValueError, "can't activate perf jit trampoline");
2372
0
                return NULL;
2373
0
            }
2374
0
        }
2375
0
    }
2376
0
    else {
2377
0
        PyErr_Format(PyExc_ValueError, "invalid backend: %s", backend);
2378
0
        return NULL;
2379
0
    }
2380
0
    if (_PyPerfTrampoline_Init(1) < 0) {
2381
0
        return NULL;
2382
0
    }
2383
0
    Py_RETURN_NONE;
2384
#else
2385
    PyErr_SetString(PyExc_ValueError, "perf trampoline not available");
2386
    return NULL;
2387
#endif
2388
0
}
2389
2390
2391
/*[clinic input]
2392
sys.deactivate_stack_trampoline
2393
2394
Deactivate the current stack profiler trampoline backend.
2395
2396
If no stack profiler is activated, this function has no effect.
2397
[clinic start generated code]*/
2398
2399
static PyObject *
2400
sys_deactivate_stack_trampoline_impl(PyObject *module)
2401
/*[clinic end generated code: output=b50da25465df0ef1 input=9f629a6be9fe7fc8]*/
2402
0
{
2403
0
    if  (_PyPerfTrampoline_Init(0) < 0) {
2404
0
        return NULL;
2405
0
    }
2406
0
    Py_RETURN_NONE;
2407
0
}
2408
2409
/*[clinic input]
2410
sys.is_stack_trampoline_active
2411
2412
Return *True* if a stack profiler trampoline is active.
2413
[clinic start generated code]*/
2414
2415
static PyObject *
2416
sys_is_stack_trampoline_active_impl(PyObject *module)
2417
/*[clinic end generated code: output=ab2746de0ad9d293 input=29616b7bf6a0b703]*/
2418
0
{
2419
0
#ifdef PY_HAVE_PERF_TRAMPOLINE
2420
0
    if (_PyIsPerfTrampolineActive()) {
2421
0
        Py_RETURN_TRUE;
2422
0
    }
2423
0
#endif
2424
0
    Py_RETURN_FALSE;
2425
0
}
2426
2427
2428
/*[clinic input]
2429
sys.is_remote_debug_enabled
2430
2431
Return True if remote debugging is enabled, False otherwise.
2432
[clinic start generated code]*/
2433
2434
static PyObject *
2435
sys_is_remote_debug_enabled_impl(PyObject *module)
2436
/*[clinic end generated code: output=7ca3d38bdd5935eb input=7335c4a2fe8cf4f3]*/
2437
0
{
2438
#if !defined(Py_REMOTE_DEBUG) || !defined(Py_SUPPORTS_REMOTE_DEBUG)
2439
    Py_RETURN_FALSE;
2440
#else
2441
0
    const PyConfig *config = _Py_GetConfig();
2442
0
    return PyBool_FromLong(config->remote_debug);
2443
0
#endif
2444
0
}
2445
2446
/*[clinic input]
2447
sys.remote_exec
2448
2449
    pid: int
2450
    script: object
2451
2452
Executes a file containing Python code in a given remote Python process.
2453
2454
This function returns immediately, and the code will be executed by the
2455
target process's main thread at the next available opportunity,
2456
similarly to how signals are handled.  There is no interface to
2457
determine when the code has been executed.  The caller is responsible
2458
for making sure that the file still exists whenever the remote process
2459
tries to read it and that it hasn't been overwritten.
2460
2461
The remote process must be running a CPython interpreter of the same
2462
major and minor version as the local process.  If either the local or
2463
remote interpreter is pre-release (alpha, beta, or release candidate)
2464
then the local and remote interpreters must be the same exact version.
2465
2466
Args:
2467
     pid (int): The process ID of the target Python process.
2468
     script (str|bytes): The path to a file containing
2469
         the Python code to be executed.
2470
[clinic start generated code]*/
2471
2472
static PyObject *
2473
sys_remote_exec_impl(PyObject *module, int pid, PyObject *script)
2474
/*[clinic end generated code: output=7d94c56afe4a52c0 input=7bd58f8da20cb74c]*/
2475
0
{
2476
0
    PyObject *path;
2477
0
    const char *debugger_script_path;
2478
2479
0
    if (PyUnicode_FSConverter(script, &path) == 0) {
2480
0
        return NULL;
2481
0
    }
2482
2483
0
    if (PySys_Audit("sys.remote_exec", "iO", pid, script) < 0) {
2484
0
        goto error;
2485
0
    }
2486
2487
0
    debugger_script_path = PyBytes_AS_STRING(path);
2488
#ifdef MS_WINDOWS
2489
    PyObject *unicode_path;
2490
    if (PyUnicode_FSDecoder(path, &unicode_path) < 0) {
2491
        goto error;
2492
    }
2493
    // Use UTF-16 (wide char) version of the path for permission checks
2494
    wchar_t *debugger_script_path_w = PyUnicode_AsWideCharString(unicode_path, NULL);
2495
    Py_DECREF(unicode_path);
2496
    if (debugger_script_path_w == NULL) {
2497
        goto error;
2498
    }
2499
    DWORD attr = GetFileAttributesW(debugger_script_path_w);
2500
    if (attr == INVALID_FILE_ATTRIBUTES) {
2501
        DWORD err = GetLastError();
2502
        PyMem_Free(debugger_script_path_w);
2503
        if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) {
2504
            PyErr_SetString(PyExc_FileNotFoundError, "Script file does not exist");
2505
        }
2506
        else if (err == ERROR_ACCESS_DENIED) {
2507
            PyErr_SetString(PyExc_PermissionError, "Script file cannot be read");
2508
        }
2509
        else {
2510
            PyErr_SetFromWindowsErr(err);
2511
        }
2512
        goto error;
2513
    }
2514
    PyMem_Free(debugger_script_path_w);
2515
#else // MS_WINDOWS
2516
0
    if (access(debugger_script_path, F_OK | R_OK) != 0) {
2517
0
        switch (errno) {
2518
0
            case ENOENT:
2519
0
                PyErr_SetString(PyExc_FileNotFoundError, "Script file does not exist");
2520
0
                break;
2521
0
            case EACCES:
2522
0
                PyErr_SetString(PyExc_PermissionError, "Script file cannot be read");
2523
0
                break;
2524
0
            default:
2525
0
                PyErr_SetFromErrno(PyExc_OSError);
2526
0
        }
2527
0
        goto error;
2528
0
    }
2529
0
#endif // MS_WINDOWS
2530
0
    if (_PySysRemoteDebug_SendExec(pid, 0, debugger_script_path) < 0) {
2531
0
        goto error;
2532
0
    }
2533
2534
0
    Py_DECREF(path);
2535
0
    Py_RETURN_NONE;
2536
2537
0
error:
2538
0
    Py_DECREF(path);
2539
0
    return NULL;
2540
0
}
2541
2542
2543
2544
/*[clinic input]
2545
sys._dump_tracelets
2546
2547
    outpath: object
2548
2549
Dump the graph of tracelets in graphviz format
2550
[clinic start generated code]*/
2551
2552
static PyObject *
2553
sys__dump_tracelets_impl(PyObject *module, PyObject *outpath)
2554
/*[clinic end generated code: output=a7fe265e2bc3b674 input=5bff6880cd28ffd1]*/
2555
0
{
2556
0
    FILE *out = Py_fopen(outpath, "wb");
2557
0
    if (out == NULL) {
2558
0
        return NULL;
2559
0
    }
2560
0
    int err = _PyDumpExecutors(out);
2561
0
    fclose(out);
2562
0
    if (err) {
2563
0
        return NULL;
2564
0
    }
2565
0
    Py_RETURN_NONE;
2566
0
}
2567
2568
2569
/*[clinic input]
2570
sys._getframemodulename
2571
2572
    depth: int = 0
2573
2574
Return the name of the module for a calling frame.
2575
2576
The default depth returns the module containing the call to this API.
2577
A more typical use in a library will pass a depth of 1 to get the user's
2578
module rather than the library module.
2579
2580
If no frame, module, or name can be found, returns None.
2581
[clinic start generated code]*/
2582
2583
static PyObject *
2584
sys__getframemodulename_impl(PyObject *module, int depth)
2585
/*[clinic end generated code: output=1d70ef691f09d2db input=d4f1a8ed43b8fb46]*/
2586
188
{
2587
188
    if (PySys_Audit("sys._getframemodulename", "i", depth) < 0) {
2588
0
        return NULL;
2589
0
    }
2590
188
    _PyInterpreterFrame *f = _PyThreadState_GET()->current_frame;
2591
384
    while (f && (_PyFrame_IsIncomplete(f) || depth-- > 0)) {
2592
196
        f = f->previous;
2593
196
    }
2594
188
    if (f == NULL || PyStackRef_IsNull(f->f_funcobj)) {
2595
0
        Py_RETURN_NONE;
2596
0
    }
2597
188
    PyObject *func = PyStackRef_AsPyObjectBorrow(f->f_funcobj);
2598
188
    PyObject *r = PyFunction_GetModule(func);
2599
188
    if (!r) {
2600
0
        PyErr_Clear();
2601
0
        r = Py_None;
2602
0
    }
2603
188
    return Py_NewRef(r);
2604
188
}
2605
2606
/*[clinic input]
2607
sys._get_cpu_count_config -> int
2608
2609
Private function for getting PyConfig.cpu_count
2610
[clinic start generated code]*/
2611
2612
static int
2613
sys__get_cpu_count_config_impl(PyObject *module)
2614
/*[clinic end generated code: output=36611bb5efad16dc input=523e1ade2204084e]*/
2615
37
{
2616
37
    const PyConfig *config = _Py_GetConfig();
2617
37
    return config->cpu_count;
2618
37
}
2619
2620
/*[clinic input]
2621
sys._baserepl
2622
2623
Private function for getting the base REPL
2624
[clinic start generated code]*/
2625
2626
static PyObject *
2627
sys__baserepl_impl(PyObject *module)
2628
/*[clinic end generated code: output=f19a36375ebe0a45 input=ade0ebb9fab56f3c]*/
2629
0
{
2630
0
    PyCompilerFlags cf = _PyCompilerFlags_INIT;
2631
0
    PyRun_AnyFileExFlags(stdin, "<stdin>", 0, &cf);
2632
0
    Py_RETURN_NONE;
2633
0
}
2634
2635
2636
/*[clinic input]
2637
sys._is_gil_enabled -> bool
2638
2639
Return True if the GIL is currently enabled and False otherwise.
2640
[clinic start generated code]*/
2641
2642
static int
2643
sys__is_gil_enabled_impl(PyObject *module)
2644
/*[clinic end generated code: output=57732cf53f5b9120 input=7e9c47f15a00e809]*/
2645
0
{
2646
#ifdef Py_GIL_DISABLED
2647
    return _PyEval_IsGILEnabled(_PyThreadState_GET());
2648
#else
2649
0
    return 1;
2650
0
#endif
2651
0
}
2652
2653
2654
#ifndef MS_WINDOWS
2655
static PerfMapState perf_map_state;
2656
#endif
2657
2658
0
PyAPI_FUNC(int) PyUnstable_PerfMapState_Init(void) {
2659
0
#ifndef MS_WINDOWS
2660
0
    char filename[100];
2661
0
    pid_t pid = getpid();
2662
    // Use nofollow flag to prevent symlink attacks.
2663
0
    int flags = O_WRONLY | O_CREAT | O_APPEND | O_NOFOLLOW;
2664
0
#ifdef O_CLOEXEC
2665
0
    flags |= O_CLOEXEC;
2666
0
#endif
2667
0
    snprintf(filename, sizeof(filename) - 1, "/tmp/perf-%jd.map",
2668
0
                (intmax_t)pid);
2669
0
    int fd = open(filename, flags, 0600);
2670
0
    if (fd == -1) {
2671
0
        return -1;
2672
0
    }
2673
0
    else{
2674
0
        perf_map_state.perf_map = fdopen(fd, "a");
2675
0
        if (perf_map_state.perf_map == NULL) {
2676
0
            close(fd);
2677
0
            return -1;
2678
0
        }
2679
0
    }
2680
0
    perf_map_state.map_lock = PyThread_allocate_lock();
2681
0
    if (perf_map_state.map_lock == NULL) {
2682
0
        fclose(perf_map_state.perf_map);
2683
0
        return -2;
2684
0
    }
2685
0
#endif
2686
0
    return 0;
2687
0
}
2688
2689
PyAPI_FUNC(int) PyUnstable_WritePerfMapEntry(
2690
    const void *code_addr,
2691
    size_t code_size,
2692
    const char *entry_name
2693
0
) {
2694
0
#ifndef MS_WINDOWS
2695
0
    if (perf_map_state.perf_map == NULL) {
2696
0
        int ret = PyUnstable_PerfMapState_Init();
2697
0
        if (ret != 0){
2698
0
            return ret;
2699
0
        }
2700
0
    }
2701
0
    PyThread_acquire_lock(perf_map_state.map_lock, 1);
2702
0
    fprintf(perf_map_state.perf_map, "%" PRIxPTR " %zx %s\n", (uintptr_t) code_addr, code_size, entry_name);
2703
0
    fflush(perf_map_state.perf_map);
2704
0
    PyThread_release_lock(perf_map_state.map_lock);
2705
0
#endif
2706
0
    return 0;
2707
0
}
2708
2709
0
PyAPI_FUNC(void) PyUnstable_PerfMapState_Fini(void) {
2710
0
#ifndef MS_WINDOWS
2711
0
    if (perf_map_state.perf_map != NULL) {
2712
        // close the file
2713
0
        PyThread_acquire_lock(perf_map_state.map_lock, 1);
2714
0
        fclose(perf_map_state.perf_map);
2715
0
        PyThread_release_lock(perf_map_state.map_lock);
2716
2717
        // clean up the lock and state
2718
0
        PyThread_free_lock(perf_map_state.map_lock);
2719
0
        perf_map_state.perf_map = NULL;
2720
0
    }
2721
0
#endif
2722
0
}
2723
2724
0
PyAPI_FUNC(int) PyUnstable_CopyPerfMapFile(const char* parent_filename) {
2725
0
#ifndef MS_WINDOWS
2726
0
    if (perf_map_state.perf_map == NULL) {
2727
0
        int ret = PyUnstable_PerfMapState_Init();
2728
0
        if (ret != 0) {
2729
0
            return ret;
2730
0
        }
2731
0
    }
2732
0
    FILE* from = fopen(parent_filename, "r");
2733
0
    if (!from) {
2734
0
        return -1;
2735
0
    }
2736
0
    char buf[4096];
2737
0
    PyThread_acquire_lock(perf_map_state.map_lock, 1);
2738
0
    int result = 0;
2739
0
    while (1) {
2740
0
        size_t bytes_read = fread(buf, 1, sizeof(buf), from);
2741
0
        if (bytes_read == 0) {
2742
0
            if (ferror(from)) {
2743
0
                result = -1;
2744
0
            }
2745
0
            break;
2746
0
        }
2747
2748
0
        size_t bytes_written = fwrite(buf, 1, bytes_read, perf_map_state.perf_map);
2749
0
        if (bytes_written < bytes_read) {
2750
0
            result = -1;
2751
0
            break;
2752
0
        }
2753
2754
0
        if (fflush(perf_map_state.perf_map) != 0) {
2755
0
            result = -1;
2756
0
            break;
2757
0
        }
2758
2759
0
        if (bytes_read < sizeof(buf) && feof(from)) {
2760
0
            break;
2761
0
        }
2762
0
    }
2763
0
    fclose(from);
2764
0
    PyThread_release_lock(perf_map_state.map_lock);
2765
0
    return result;
2766
0
#endif
2767
0
    return 0;
2768
0
}
2769
2770
/*[clinic input]
2771
sys.set_lazy_imports_filter
2772
2773
    filter: object
2774
2775
Set the lazy imports filter callback.
2776
2777
The filter is a callable which disables lazy imports when they
2778
would otherwise be enabled. Returns True if the import is still enabled
2779
or False to disable it. The callable is called with:
2780
2781
(importing_module_name, resolved_imported_module_name, [fromlist])
2782
2783
Pass None to clear the filter.
2784
[clinic start generated code]*/
2785
2786
static PyObject *
2787
sys_set_lazy_imports_filter_impl(PyObject *module, PyObject *filter)
2788
/*[clinic end generated code: output=10251d49469c278c input=fd51ed8df6ab54b7]*/
2789
0
{
2790
0
    if (PyImport_SetLazyImportsFilter(filter) < 0) {
2791
0
        return NULL;
2792
0
    }
2793
2794
0
    Py_RETURN_NONE;
2795
0
}
2796
2797
/*[clinic input]
2798
sys.get_lazy_imports_filter
2799
2800
Get the current lazy imports filter callback.
2801
2802
Returns the filter callable or None if no filter is set.
2803
[clinic start generated code]*/
2804
2805
static PyObject *
2806
sys_get_lazy_imports_filter_impl(PyObject *module)
2807
/*[clinic end generated code: output=3bf73022892165af input=cf1e07cb8e203c94]*/
2808
0
{
2809
0
    PyObject *filter = PyImport_GetLazyImportsFilter();
2810
0
    if (filter == NULL) {
2811
0
        assert(!PyErr_Occurred());
2812
0
        Py_RETURN_NONE;
2813
0
    }
2814
0
    return filter;
2815
0
}
2816
2817
/*[clinic input]
2818
sys.set_lazy_imports
2819
2820
    mode: object
2821
2822
Sets the global lazy imports mode.
2823
2824
The mode parameter must be one of the following strings:
2825
- "all": All top-level imports become potentially lazy
2826
- "normal": Only explicitly marked imports (with 'lazy' keyword) are
2827
  lazy
2828
2829
In addition to the mode, lazy imports can be controlled via the filter
2830
provided to sys.set_lazy_imports_filter
2831
2832
[clinic start generated code]*/
2833
2834
static PyObject *
2835
sys_set_lazy_imports_impl(PyObject *module, PyObject *mode)
2836
/*[clinic end generated code: output=1ff34ba6c4feaf73 input=db3242f0ff6e5dcc]*/
2837
0
{
2838
0
    PyImport_LazyImportsMode lazy_mode;
2839
0
    if (!PyUnicode_Check(mode)) {
2840
0
        PyErr_SetString(PyExc_TypeError,
2841
0
                        "mode must be a string: 'normal' or 'all'");
2842
0
        return NULL;
2843
0
    }
2844
0
    if (PyUnicode_CompareWithASCIIString(mode, "normal") == 0) {
2845
0
        lazy_mode = PyImport_LAZY_NORMAL;
2846
0
    }
2847
0
    else if (PyUnicode_CompareWithASCIIString(mode, "all") == 0) {
2848
0
        lazy_mode = PyImport_LAZY_ALL;
2849
0
    }
2850
0
    else {
2851
0
        PyErr_SetString(PyExc_ValueError,
2852
0
                        "mode must be 'normal' or 'all'");
2853
0
        return NULL;
2854
0
    }
2855
2856
0
    if (PyImport_SetLazyImportsMode(lazy_mode)) {
2857
0
        return NULL;
2858
0
    }
2859
0
    Py_RETURN_NONE;
2860
0
}
2861
2862
/*[clinic input]
2863
sys.get_lazy_imports
2864
2865
Gets the global lazy imports mode.
2866
2867
Returns "all" if all top level imports are potentially lazy.
2868
Returns "normal" if only explicitly marked imports are lazy.
2869
2870
[clinic start generated code]*/
2871
2872
static PyObject *
2873
sys_get_lazy_imports_impl(PyObject *module)
2874
/*[clinic end generated code: output=4147dec48c51ae99 input=6f8dd4f2c82893f2]*/
2875
0
{
2876
0
    switch (PyImport_GetLazyImportsMode()) {
2877
0
        case PyImport_LAZY_NORMAL:
2878
0
            return PyUnicode_FromString("normal");
2879
0
        case PyImport_LAZY_ALL:
2880
0
            return PyUnicode_FromString("all");
2881
0
        default:
2882
0
            PyErr_SetString(PyExc_RuntimeError, "unknown lazy imports mode");
2883
0
            return NULL;
2884
0
    }
2885
0
}
2886
2887
static PyMethodDef sys_methods[] = {
2888
    /* Might as well keep this in alphabetic order */
2889
    SYS_ADDAUDITHOOK_METHODDEF
2890
    SYS_AUDIT_METHODDEF
2891
    {"breakpointhook", _PyCFunction_CAST(sys_breakpointhook),
2892
     METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc},
2893
    SYS__CLEAR_INTERNAL_CACHES_METHODDEF
2894
    SYS__CLEAR_TYPE_CACHE_METHODDEF
2895
    SYS__CURRENT_FRAMES_METHODDEF
2896
    SYS__CURRENT_EXCEPTIONS_METHODDEF
2897
    SYS_DISPLAYHOOK_METHODDEF
2898
    SYS_EXCEPTION_METHODDEF
2899
    SYS_EXC_INFO_METHODDEF
2900
    SYS_EXCEPTHOOK_METHODDEF
2901
    SYS_EXIT_METHODDEF
2902
    SYS_GETDEFAULTENCODING_METHODDEF
2903
    SYS_GETDLOPENFLAGS_METHODDEF
2904
    SYS_GETALLOCATEDBLOCKS_METHODDEF
2905
    SYS_GETUNICODEINTERNEDSIZE_METHODDEF
2906
    SYS_GETFILESYSTEMENCODING_METHODDEF
2907
    SYS_GETFILESYSTEMENCODEERRORS_METHODDEF
2908
#ifdef Py_TRACE_REFS
2909
    {"getobjects", _Py_GetObjects, METH_VARARGS},
2910
#endif
2911
    SYS_GETTOTALREFCOUNT_METHODDEF
2912
    SYS_GETREFCOUNT_METHODDEF
2913
    SYS_GETRECURSIONLIMIT_METHODDEF
2914
    SYS_GETSIZEOF_METHODDEF
2915
    SYS__GETFRAME_METHODDEF
2916
    SYS__GETFRAMEMODULENAME_METHODDEF
2917
    SYS_GETWINDOWSVERSION_METHODDEF
2918
    SYS__IS_IMMORTAL_METHODDEF
2919
    SYS_INTERN_METHODDEF
2920
    SYS__IS_INTERNED_METHODDEF
2921
    SYS_IS_FINALIZING_METHODDEF
2922
    SYS_MDEBUG_METHODDEF
2923
    SYS_SETSWITCHINTERVAL_METHODDEF
2924
    SYS_GETSWITCHINTERVAL_METHODDEF
2925
    SYS_SETDLOPENFLAGS_METHODDEF
2926
    SYS_SETPROFILE_METHODDEF
2927
    SYS__SETPROFILEALLTHREADS_METHODDEF
2928
    SYS_GETPROFILE_METHODDEF
2929
    SYS_SETRECURSIONLIMIT_METHODDEF
2930
    SYS_SETTRACE_METHODDEF
2931
    SYS__SETTRACEALLTHREADS_METHODDEF
2932
    SYS_GETTRACE_METHODDEF
2933
    SYS_CALL_TRACING_METHODDEF
2934
    SYS__DEBUGMALLOCSTATS_METHODDEF
2935
    SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF
2936
    SYS_GET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF
2937
    SYS_SET_ASYNCGEN_HOOKS_METHODDEF
2938
    SYS_GET_ASYNCGEN_HOOKS_METHODDEF
2939
    SYS_GETANDROIDAPILEVEL_METHODDEF
2940
    SYS_ACTIVATE_STACK_TRAMPOLINE_METHODDEF
2941
    SYS_DEACTIVATE_STACK_TRAMPOLINE_METHODDEF
2942
    SYS_IS_STACK_TRAMPOLINE_ACTIVE_METHODDEF
2943
    SYS_IS_REMOTE_DEBUG_ENABLED_METHODDEF
2944
    SYS_REMOTE_EXEC_METHODDEF
2945
    SYS_UNRAISABLEHOOK_METHODDEF
2946
    SYS_GET_INT_MAX_STR_DIGITS_METHODDEF
2947
    SYS_SET_INT_MAX_STR_DIGITS_METHODDEF
2948
    SYS_GET_LAZY_IMPORTS_METHODDEF
2949
    SYS_SET_LAZY_IMPORTS_METHODDEF
2950
    SYS_GET_LAZY_IMPORTS_FILTER_METHODDEF
2951
    SYS_SET_LAZY_IMPORTS_FILTER_METHODDEF
2952
    SYS__BASEREPL_METHODDEF
2953
#ifdef Py_STATS
2954
    SYS__STATS_ON_METHODDEF
2955
    SYS__STATS_OFF_METHODDEF
2956
    SYS__STATS_CLEAR_METHODDEF
2957
    SYS__STATS_DUMP_METHODDEF
2958
#endif
2959
    SYS__GET_CPU_COUNT_CONFIG_METHODDEF
2960
    SYS__IS_GIL_ENABLED_METHODDEF
2961
    SYS__DUMP_TRACELETS_METHODDEF
2962
    {NULL, NULL}  // sentinel
2963
};
2964
2965
2966
static PyObject *
2967
list_builtin_module_names(void)
2968
37
{
2969
37
    PyObject *list = _PyImport_GetBuiltinModuleNames();
2970
37
    if (list == NULL) {
2971
0
        return NULL;
2972
0
    }
2973
37
    if (PyList_Sort(list) != 0) {
2974
0
        goto error;
2975
0
    }
2976
37
    PyObject *tuple = PyList_AsTuple(list);
2977
37
    Py_DECREF(list);
2978
37
    return tuple;
2979
2980
0
error:
2981
0
    Py_DECREF(list);
2982
0
    return NULL;
2983
37
}
2984
2985
2986
static PyObject *
2987
list_stdlib_module_names(void)
2988
37
{
2989
37
    Py_ssize_t len = Py_ARRAY_LENGTH(_Py_stdlib_module_names);
2990
37
    PyObject *names = PyTuple_New(len);
2991
37
    if (names == NULL) {
2992
0
        return NULL;
2993
0
    }
2994
2995
11.0k
    for (Py_ssize_t i = 0; i < len; i++) {
2996
10.9k
        PyObject *name = PyUnicode_FromString(_Py_stdlib_module_names[i]);
2997
10.9k
        if (name == NULL) {
2998
0
            Py_DECREF(names);
2999
0
            return NULL;
3000
0
        }
3001
10.9k
        PyTuple_SET_ITEM(names, i, name);
3002
10.9k
    }
3003
3004
37
    PyObject *set = PyObject_CallFunction((PyObject *)&PyFrozenSet_Type,
3005
37
                                          "(O)", names);
3006
37
    Py_DECREF(names);
3007
37
    return set;
3008
37
}
3009
3010
3011
/* Pre-initialization support for sys.warnoptions and sys._xoptions
3012
 *
3013
 * Modern internal code paths:
3014
 *   These APIs get called after _Py_InitializeCore and get to use the
3015
 *   regular CPython list, dict, and unicode APIs.
3016
 *
3017
 * Legacy embedding code paths:
3018
 *   The multi-phase initialization API isn't public yet, so embedding
3019
 *   apps still need to be able configure sys.warnoptions and sys._xoptions
3020
 *   before they call Py_Initialize. To support this, we stash copies of
3021
 *   the supplied wchar * sequences in linked lists, and then migrate the
3022
 *   contents of those lists to the sys module in _PyInitializeCore.
3023
 *
3024
 */
3025
3026
struct _preinit_entry {
3027
    wchar_t *value;
3028
    struct _preinit_entry *next;
3029
};
3030
3031
typedef struct _preinit_entry *_Py_PreInitEntry;
3032
3033
static _Py_PreInitEntry _preinit_warnoptions = NULL;
3034
static _Py_PreInitEntry _preinit_xoptions = NULL;
3035
3036
static _Py_PreInitEntry
3037
_alloc_preinit_entry(const wchar_t *value)
3038
0
{
3039
    /* To get this to work, we have to initialize the runtime implicitly */
3040
0
    _PyRuntime_Initialize();
3041
3042
    /* Use the default allocator, so we can ensure that it also gets used to
3043
     * destroy the linked list in _clear_preinit_entries.
3044
     */
3045
0
    _Py_PreInitEntry node = _PyMem_DefaultRawCalloc(1, sizeof(*node));
3046
0
    if (node != NULL) {
3047
0
        node->value = _PyMem_DefaultRawWcsdup(value);
3048
0
        if (node->value == NULL) {
3049
0
            _PyMem_DefaultRawFree(node);
3050
0
            node = NULL;
3051
0
        };
3052
0
    };
3053
0
    return node;
3054
0
}
3055
3056
static int
3057
_append_preinit_entry(_Py_PreInitEntry *optionlist, const wchar_t *value)
3058
0
{
3059
0
    _Py_PreInitEntry new_entry = _alloc_preinit_entry(value);
3060
0
    if (new_entry == NULL) {
3061
0
        return -1;
3062
0
    }
3063
    /* We maintain the linked list in this order so it's easy to play back
3064
     * the add commands in the same order later on in _Py_InitializeCore
3065
     */
3066
0
    _Py_PreInitEntry last_entry = *optionlist;
3067
0
    if (last_entry == NULL) {
3068
0
        *optionlist = new_entry;
3069
0
    } else {
3070
0
        while (last_entry->next != NULL) {
3071
0
            last_entry = last_entry->next;
3072
0
        }
3073
0
        last_entry->next = new_entry;
3074
0
    }
3075
0
    return 0;
3076
0
}
3077
3078
static void
3079
_clear_preinit_entries(_Py_PreInitEntry *optionlist)
3080
74
{
3081
74
    _Py_PreInitEntry current = *optionlist;
3082
74
    *optionlist = NULL;
3083
    /* Deallocate the nodes and their contents using the default allocator */
3084
74
    while (current != NULL) {
3085
0
        _Py_PreInitEntry next = current->next;
3086
0
        _PyMem_DefaultRawFree(current->value);
3087
0
        _PyMem_DefaultRawFree(current);
3088
0
        current = next;
3089
0
    }
3090
74
}
3091
3092
3093
PyStatus
3094
_PySys_ReadPreinitWarnOptions(PyWideStringList *options)
3095
37
{
3096
37
    PyStatus status;
3097
37
    _Py_PreInitEntry entry;
3098
3099
37
    for (entry = _preinit_warnoptions; entry != NULL; entry = entry->next) {
3100
0
        status = PyWideStringList_Append(options, entry->value);
3101
0
        if (_PyStatus_EXCEPTION(status)) {
3102
0
            return status;
3103
0
        }
3104
0
    }
3105
3106
37
    _clear_preinit_entries(&_preinit_warnoptions);
3107
37
    return _PyStatus_OK();
3108
37
}
3109
3110
3111
PyStatus
3112
_PySys_ReadPreinitXOptions(PyConfig *config)
3113
37
{
3114
37
    PyStatus status;
3115
37
    _Py_PreInitEntry entry;
3116
3117
37
    for (entry = _preinit_xoptions; entry != NULL; entry = entry->next) {
3118
0
        status = PyWideStringList_Append(&config->xoptions, entry->value);
3119
0
        if (_PyStatus_EXCEPTION(status)) {
3120
0
            return status;
3121
0
        }
3122
0
    }
3123
3124
37
    _clear_preinit_entries(&_preinit_xoptions);
3125
37
    return _PyStatus_OK();
3126
37
}
3127
3128
3129
static PyObject *
3130
get_warnoptions(PyThreadState *tstate)
3131
0
{
3132
0
    PyObject *warnoptions;
3133
0
    if (PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
3134
0
        return NULL;
3135
0
    }
3136
0
    if (warnoptions == NULL || !PyList_Check(warnoptions)) {
3137
        /* PEP432 TODO: we can reach this if warnoptions is NULL in the main
3138
        *  interpreter config. When that happens, we need to properly set
3139
         * the `warnoptions` reference in the main interpreter config as well.
3140
         *
3141
         * For Python 3.7, we shouldn't be able to get here due to the
3142
         * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit
3143
         * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig
3144
         * call optional for embedding applications, thus making this
3145
         * reachable again.
3146
         */
3147
0
        Py_XDECREF(warnoptions);
3148
0
        warnoptions = PyList_New(0);
3149
0
        if (warnoptions == NULL) {
3150
0
            return NULL;
3151
0
        }
3152
0
        if (sys_set_object(tstate->interp, &_Py_ID(warnoptions), warnoptions)) {
3153
0
            Py_DECREF(warnoptions);
3154
0
            return NULL;
3155
0
        }
3156
0
    }
3157
0
    return warnoptions;
3158
0
}
3159
3160
PyAPI_FUNC(void)
3161
PySys_ResetWarnOptions(void)
3162
0
{
3163
0
    PyThreadState *tstate = _PyThreadState_GET();
3164
0
    if (tstate == NULL) {
3165
0
        _clear_preinit_entries(&_preinit_warnoptions);
3166
0
        return;
3167
0
    }
3168
3169
0
    PyObject *warnoptions;
3170
0
    if (PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
3171
0
        PyErr_Clear();
3172
0
        return;
3173
0
    }
3174
0
    if (warnoptions != NULL && PyList_Check(warnoptions)) {
3175
0
        PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
3176
0
    }
3177
0
    Py_XDECREF(warnoptions);
3178
0
}
3179
3180
static int
3181
_PySys_AddWarnOptionWithError(PyThreadState *tstate, PyObject *option)
3182
0
{
3183
0
    assert(tstate != NULL);
3184
0
    PyObject *warnoptions = get_warnoptions(tstate);
3185
0
    if (warnoptions == NULL) {
3186
0
        return -1;
3187
0
    }
3188
0
    if (PyList_Append(warnoptions, option)) {
3189
0
        Py_DECREF(warnoptions);
3190
0
        return -1;
3191
0
    }
3192
0
    Py_DECREF(warnoptions);
3193
0
    return 0;
3194
0
}
3195
3196
// Removed in Python 3.13 API, but kept for the stable ABI
3197
PyAPI_FUNC(void)
3198
PySys_AddWarnOptionUnicode(PyObject *option)
3199
0
{
3200
0
    PyThreadState *tstate = _PyThreadState_GET();
3201
0
    _Py_EnsureTstateNotNULL(tstate);
3202
0
    assert(!_PyErr_Occurred(tstate));
3203
0
    if (_PySys_AddWarnOptionWithError(tstate, option) < 0) {
3204
        /* No return value, therefore clear error state if possible */
3205
0
        _PyErr_Clear(tstate);
3206
0
    }
3207
0
}
3208
3209
// Removed in Python 3.13 API, but kept for the stable ABI
3210
PyAPI_FUNC(void)
3211
PySys_AddWarnOption(const wchar_t *s)
3212
0
{
3213
0
    PyThreadState *tstate = _PyThreadState_GET();
3214
0
    if (tstate == NULL) {
3215
0
        _append_preinit_entry(&_preinit_warnoptions, s);
3216
0
        return;
3217
0
    }
3218
0
    PyObject *unicode;
3219
0
    unicode = PyUnicode_FromWideChar(s, -1);
3220
0
    if (unicode == NULL)
3221
0
        return;
3222
0
_Py_COMP_DIAG_PUSH
3223
0
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
3224
0
    PySys_AddWarnOptionUnicode(unicode);
3225
0
_Py_COMP_DIAG_POP
3226
0
    Py_DECREF(unicode);
3227
0
}
3228
3229
// Removed in Python 3.13 API, but kept for the stable ABI
3230
PyAPI_FUNC(int)
3231
PySys_HasWarnOptions(void)
3232
0
{
3233
0
    PyObject *warnoptions;
3234
0
    if (PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
3235
0
        PyErr_Clear();
3236
0
        return 0;
3237
0
    }
3238
0
    int r = (warnoptions != NULL && PyList_Check(warnoptions) &&
3239
0
             PyList_GET_SIZE(warnoptions) > 0);
3240
0
    Py_XDECREF(warnoptions);
3241
0
    return r;
3242
0
}
3243
3244
static PyObject *
3245
get_xoptions(PyThreadState *tstate)
3246
0
{
3247
0
    PyObject *xoptions;
3248
0
    if (PySys_GetOptionalAttr(&_Py_ID(_xoptions), &xoptions) < 0) {
3249
0
        return NULL;
3250
0
    }
3251
0
    if (xoptions == NULL || !PyDict_Check(xoptions)) {
3252
        /* PEP432 TODO: we can reach this if xoptions is NULL in the main
3253
        *  interpreter config. When that happens, we need to properly set
3254
         * the `xoptions` reference in the main interpreter config as well.
3255
         *
3256
         * For Python 3.7, we shouldn't be able to get here due to the
3257
         * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit
3258
         * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig
3259
         * call optional for embedding applications, thus making this
3260
         * reachable again.
3261
         */
3262
0
        Py_XDECREF(xoptions);
3263
0
        xoptions = PyDict_New();
3264
0
        if (xoptions == NULL) {
3265
0
            return NULL;
3266
0
        }
3267
0
        if (sys_set_object(tstate->interp, &_Py_ID(_xoptions), xoptions)) {
3268
0
            Py_DECREF(xoptions);
3269
0
            return NULL;
3270
0
        }
3271
0
    }
3272
0
    return xoptions;
3273
0
}
3274
3275
static int
3276
_PySys_AddXOptionWithError(const wchar_t *s)
3277
0
{
3278
0
    PyObject *name = NULL, *value = NULL;
3279
3280
0
    PyThreadState *tstate = _PyThreadState_GET();
3281
0
    PyObject *opts = get_xoptions(tstate);
3282
0
    if (opts == NULL) {
3283
0
        goto error;
3284
0
    }
3285
3286
0
    const wchar_t *name_end = wcschr(s, L'=');
3287
0
    if (!name_end) {
3288
0
        name = PyUnicode_FromWideChar(s, -1);
3289
0
        if (name == NULL) {
3290
0
            goto error;
3291
0
        }
3292
0
        value = Py_NewRef(Py_True);
3293
0
    }
3294
0
    else {
3295
0
        name = PyUnicode_FromWideChar(s, name_end - s);
3296
0
        if (name == NULL) {
3297
0
            goto error;
3298
0
        }
3299
0
        value = PyUnicode_FromWideChar(name_end + 1, -1);
3300
0
        if (value == NULL) {
3301
0
            goto error;
3302
0
        }
3303
0
    }
3304
0
    if (PyDict_SetItem(opts, name, value) < 0) {
3305
0
        goto error;
3306
0
    }
3307
0
    Py_DECREF(name);
3308
0
    Py_DECREF(value);
3309
0
    Py_DECREF(opts);
3310
0
    return 0;
3311
3312
0
error:
3313
0
    Py_XDECREF(name);
3314
0
    Py_XDECREF(value);
3315
0
    Py_XDECREF(opts);
3316
0
    return -1;
3317
0
}
3318
3319
// Removed in Python 3.13 API, but kept for the stable ABI
3320
PyAPI_FUNC(void)
3321
PySys_AddXOption(const wchar_t *s)
3322
0
{
3323
0
    PyThreadState *tstate = _PyThreadState_GET();
3324
0
    if (tstate == NULL) {
3325
0
        _append_preinit_entry(&_preinit_xoptions, s);
3326
0
        return;
3327
0
    }
3328
0
    if (_PySys_AddXOptionWithError(s) < 0) {
3329
        /* No return value, therefore clear error state if possible */
3330
0
        _PyErr_Clear(tstate);
3331
0
    }
3332
0
}
3333
3334
PyObject *
3335
PySys_GetXOptions(void)
3336
0
{
3337
0
    PyThreadState *tstate = _PyThreadState_GET();
3338
0
    PyObject *opts = get_xoptions(tstate);
3339
0
    Py_XDECREF(opts);
3340
0
    return opts;
3341
0
}
3342
3343
/* XXX This doc string is too long to be a single string literal in VC++ 5.0.
3344
   Two literals concatenated works just fine.  If you have a K&R compiler
3345
   or other abomination that however *does* understand longer strings,
3346
   get rid of the !!! comment in the middle and the quotes that surround it. */
3347
PyDoc_VAR(sys_doc) =
3348
PyDoc_STR(
3349
"This module provides access to some objects used or maintained by the\n\
3350
interpreter and to functions that interact strongly with the interpreter.\n\
3351
\n\
3352
Dynamic objects:\n\
3353
\n\
3354
argv -- command line arguments; argv[0] is the script pathname if known\n\
3355
path -- module search path; path[0] is the script directory, else ''\n\
3356
modules -- dictionary of loaded modules\n\
3357
\n\
3358
displayhook -- called to show results in an interactive session\n\
3359
excepthook -- called to handle any uncaught exception other than SystemExit\n\
3360
  To customize printing in an interactive session or to install a custom\n\
3361
  top-level exception handler, assign other functions to replace these.\n\
3362
\n\
3363
stdin -- standard input file object; used by input()\n\
3364
stdout -- standard output file object; used by print()\n\
3365
stderr -- standard error object; used for error messages\n\
3366
  By assigning other file objects (or objects that behave like files)\n\
3367
  to these, it is possible to redirect all of the interpreter's I/O.\n\
3368
\n\
3369
last_exc - the last uncaught exception\n\
3370
  Only available in an interactive session after a\n\
3371
  traceback has been printed.\n\
3372
last_type -- type of last uncaught exception\n\
3373
last_value -- value of last uncaught exception\n\
3374
last_traceback -- traceback of last uncaught exception\n\
3375
  These three are the (deprecated) legacy representation of last_exc.\n\
3376
"
3377
)
3378
/* concatenating string here */
3379
PyDoc_STR(
3380
"\n\
3381
Static objects:\n\
3382
\n\
3383
abi_info -- Python ABI information.\n\
3384
builtin_module_names -- tuple of module names built into this interpreter\n\
3385
copyright -- copyright notice pertaining to this interpreter\n\
3386
exec_prefix -- prefix used to find the machine-specific Python library\n\
3387
executable -- absolute path of the executable binary of the Python interpreter\n\
3388
float_info -- a named tuple with information about the float implementation.\n\
3389
float_repr_style -- string indicating the style of repr() output for floats\n\
3390
hash_info -- a named tuple with information about the hash algorithm.\n\
3391
hexversion -- version information encoded as a single integer\n\
3392
implementation -- Python implementation information.\n\
3393
int_info -- a named tuple with information about the int implementation.\n\
3394
maxsize -- the largest supported length of containers.\n\
3395
maxunicode -- the value of the largest Unicode code point\n\
3396
platform -- platform identifier\n\
3397
prefix -- prefix used to find the Python library\n\
3398
thread_info -- a named tuple with information about the thread implementation.\n\
3399
version -- the version of this interpreter as a string\n\
3400
version_info -- version information as a named tuple\n\
3401
"
3402
)
3403
#ifdef MS_COREDLL
3404
/* concatenating string here */
3405
PyDoc_STR(
3406
"dllhandle -- [Windows only] integer handle of the Python DLL\n\
3407
winver -- [Windows only] version number of the Python DLL\n\
3408
"
3409
)
3410
#endif /* MS_COREDLL */
3411
PyDoc_STR(
3412
"__stdin__ -- the original stdin; don't touch!\n\
3413
__stdout__ -- the original stdout; don't touch!\n\
3414
__stderr__ -- the original stderr; don't touch!\n\
3415
__displayhook__ -- the original displayhook; don't touch!\n\
3416
__excepthook__ -- the original excepthook; don't touch!\n\
3417
\n\
3418
Functions:\n\
3419
\n\
3420
displayhook() -- print an object to the screen, and save it in builtins._\n\
3421
excepthook() -- print an exception and its traceback to sys.stderr\n\
3422
exception() -- return the current thread's active exception\n\
3423
exc_info() -- return information about the current thread's active exception\n\
3424
exit() -- exit the interpreter by raising SystemExit\n\
3425
getdlopenflags() -- returns flags to be used for dlopen() calls\n\
3426
getprofile() -- get the global profiling function\n\
3427
getrefcount() -- return the reference count for an object (plus one :-)\n\
3428
getrecursionlimit() -- return the max recursion depth for the interpreter\n\
3429
getsizeof() -- return the size of an object in bytes\n\
3430
gettrace() -- get the global debug tracing function\n\
3431
setdlopenflags() -- set the flags to be used for dlopen() calls\n\
3432
setprofile() -- set the global profiling function\n\
3433
setrecursionlimit() -- set the max recursion depth for the interpreter\n\
3434
settrace() -- set the global debug tracing function\n\
3435
"
3436
)
3437
/* end of sys_doc */ ;
3438
3439
3440
PyDoc_STRVAR(flags__doc__,
3441
"sys.flags\n\
3442
\n\
3443
Flags provided through command line arguments or environment vars.");
3444
3445
static PyTypeObject FlagsType;
3446
3447
static PyStructSequence_Field flags_fields[] = {
3448
    {"debug",                   "-d"},
3449
    {"inspect",                 "-i"},
3450
    {"interactive",             "-i"},
3451
    {"optimize",                "-O or -OO"},
3452
    {"dont_write_bytecode",     "-B"},
3453
    {"no_user_site",            "-s"},
3454
    {"no_site",                 "-S"},
3455
    {"ignore_environment",      "-E"},
3456
    {"verbose",                 "-v"},
3457
    {"bytes_warning",           "-b"},
3458
    {"quiet",                   "-q"},
3459
    {"hash_randomization",      "-R"},
3460
    {"isolated",                "-I"},
3461
    {"dev_mode",                "-X dev"},
3462
    {"utf8_mode",               "-X utf8"},
3463
    {"warn_default_encoding",   "-X warn_default_encoding"},
3464
    {"safe_path",               "-P"},
3465
    {"int_max_str_digits",      "-X int_max_str_digits"},
3466
    // Fields below are only usable by sys.flags attribute name, not index:
3467
    {"gil",                     "-X gil"},
3468
    {"thread_inherit_context",  "-X thread_inherit_context"},
3469
    {"context_aware_warnings",  "-X context_aware_warnings"},
3470
    {"lazy_imports",            "-X lazy_imports"},
3471
    {0}
3472
};
3473
3474
0
#define SYS_FLAGS_INT_MAX_STR_DIGITS 17
3475
3476
static PyStructSequence_Desc flags_desc = {
3477
    "sys.flags",        /* name */
3478
    flags__doc__,       /* doc */
3479
    flags_fields,       /* fields */
3480
    18  /* NB - do not increase beyond 3.13's value of 18. */
3481
    // New sys.flags fields should NOT be tuple addressable per
3482
    // https://github.com/python/cpython/issues/122575#issuecomment-2416497086
3483
};
3484
3485
static void
3486
sys_set_flag(PyObject *flags, Py_ssize_t pos, PyObject *value)
3487
1.62k
{
3488
1.62k
    assert(pos >= 0 && pos < (Py_ssize_t)(Py_ARRAY_LENGTH(flags_fields) - 1));
3489
3490
1.62k
    PyObject *old_value = PyStructSequence_GET_ITEM(flags, pos);
3491
1.62k
    PyStructSequence_SET_ITEM(flags, pos, Py_NewRef(value));
3492
1.62k
    Py_XDECREF(old_value);
3493
1.62k
}
3494
3495
3496
int
3497
_PySys_SetFlagObj(Py_ssize_t pos, PyObject *value)
3498
0
{
3499
0
    PyObject *new_flags = NULL;
3500
0
    PyObject *flags_str = &_Py_ID(flags);  // immortal ref
3501
3502
0
    PyObject *old_flags = PySys_GetAttr(flags_str);
3503
0
    if (old_flags == NULL) {
3504
0
        goto error;
3505
0
    }
3506
3507
0
    new_flags = PyStructSequence_New(&FlagsType);
3508
0
    if (new_flags == NULL) {
3509
0
        goto error;
3510
0
    }
3511
3512
0
    for (Py_ssize_t i = 0; i < (Py_ssize_t)(Py_ARRAY_LENGTH(flags_fields) - 1); i++) {
3513
0
        if (i != pos) {
3514
0
            PyObject *old_value;
3515
0
            old_value = PyStructSequence_GET_ITEM(old_flags, i);  // borrowed ref
3516
0
            sys_set_flag(new_flags, i, old_value);
3517
0
        }
3518
0
        else {
3519
0
            sys_set_flag(new_flags, pos, value);
3520
0
        }
3521
0
    }
3522
3523
0
    int res = _PySys_SetAttr(flags_str, new_flags);
3524
0
    Py_DECREF(old_flags);
3525
0
    Py_DECREF(new_flags);
3526
0
    return res;
3527
3528
0
error:
3529
0
    Py_XDECREF(old_flags);
3530
0
    Py_XDECREF(new_flags);
3531
0
    return -1;
3532
0
}
3533
3534
3535
static int
3536
_PySys_SetFlagInt(Py_ssize_t pos, int value)
3537
0
{
3538
0
    PyObject *obj = PyLong_FromLong(value);
3539
0
    if (obj == NULL) {
3540
0
        return -1;
3541
0
    }
3542
3543
0
    int res = _PySys_SetFlagObj(pos, obj);
3544
0
    Py_DECREF(obj);
3545
0
    return res;
3546
0
}
3547
3548
3549
static int
3550
set_flags_from_config(PyInterpreterState *interp, PyObject *flags)
3551
74
{
3552
74
    const PyPreConfig *preconfig = &interp->runtime->preconfig;
3553
74
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);
3554
3555
74
    Py_ssize_t pos = 0;
3556
74
#define SetFlagObj(expr) \
3557
1.62k
    do { \
3558
1.62k
        PyObject *value = (expr); \
3559
1.62k
        if (value == NULL) { \
3560
0
            return -1; \
3561
0
        } \
3562
1.62k
        sys_set_flag(flags, pos, value); \
3563
1.62k
        Py_DECREF(value); \
3564
1.62k
        pos++; \
3565
1.62k
    } while (0)
3566
1.40k
#define SetFlag(expr) SetFlagObj(PyLong_FromLong(expr))
3567
3568
74
    SetFlag(config->parser_debug);
3569
74
    SetFlag(config->inspect);
3570
74
    SetFlag(config->interactive);
3571
74
    SetFlag(config->optimization_level);
3572
74
    SetFlag(!config->write_bytecode);
3573
74
    SetFlag(!config->user_site_directory);
3574
74
    SetFlag(!config->site_import);
3575
74
    SetFlag(!config->use_environment);
3576
74
    SetFlag(config->verbose);
3577
74
    SetFlag(config->bytes_warning);
3578
74
    SetFlag(config->quiet);
3579
74
    SetFlag(config->use_hash_seed == 0 || config->hash_seed != 0);
3580
74
    SetFlag(config->isolated);
3581
74
    SetFlagObj(PyBool_FromLong(config->dev_mode));
3582
74
    SetFlag(preconfig->utf8_mode);
3583
74
    SetFlag(config->warn_default_encoding);
3584
74
    SetFlagObj(PyBool_FromLong(config->safe_path));
3585
74
    SetFlag(config->int_max_str_digits);
3586
#ifdef Py_GIL_DISABLED
3587
    if (config->enable_gil == _PyConfig_GIL_DEFAULT) {
3588
        SetFlagObj(Py_NewRef(Py_None));
3589
    }
3590
    else {
3591
        SetFlag(config->enable_gil);
3592
    }
3593
#else
3594
74
    SetFlagObj(PyLong_FromLong(1));
3595
74
#endif
3596
74
    SetFlag(config->thread_inherit_context);
3597
74
    SetFlag(config->context_aware_warnings);
3598
74
    SetFlag(config->lazy_imports);
3599
74
#undef SetFlagObj
3600
74
#undef SetFlag
3601
74
    return 0;
3602
74
}
3603
3604
3605
static PyObject*
3606
make_flags(PyInterpreterState *interp)
3607
37
{
3608
37
    PyObject *flags = PyStructSequence_New(&FlagsType);
3609
37
    if (flags == NULL) {
3610
0
        return NULL;
3611
0
    }
3612
3613
37
    if (set_flags_from_config(interp, flags) < 0) {
3614
0
        Py_DECREF(flags);
3615
0
        return NULL;
3616
0
    }
3617
37
    return flags;
3618
37
}
3619
3620
3621
PyDoc_STRVAR(version_info__doc__,
3622
"sys.version_info\n\
3623
\n\
3624
Version information as a named tuple.");
3625
3626
static PyTypeObject VersionInfoType;
3627
3628
static PyStructSequence_Field version_info_fields[] = {
3629
    {"major", "Major release number"},
3630
    {"minor", "Minor release number"},
3631
    {"micro", "Patch release number"},
3632
    {"releaselevel", "'alpha', 'beta', 'candidate', or 'final'"},
3633
    {"serial", "Serial release number"},
3634
    {0}
3635
};
3636
3637
static PyStructSequence_Desc version_info_desc = {
3638
    "sys.version_info",     /* name */
3639
    version_info__doc__,    /* doc */
3640
    version_info_fields,    /* fields */
3641
    5
3642
};
3643
3644
static PyObject *
3645
make_version_info(PyThreadState *tstate)
3646
37
{
3647
37
    PyObject *version_info;
3648
37
    char *s;
3649
37
    int pos = 0;
3650
3651
37
    version_info = PyStructSequence_New(&VersionInfoType);
3652
37
    if (version_info == NULL) {
3653
0
        return NULL;
3654
0
    }
3655
3656
    /*
3657
     * These release level checks are mutually exclusive and cover
3658
     * the field, so don't get too fancy with the pre-processor!
3659
     */
3660
37
#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
3661
37
    s = "alpha";
3662
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
3663
    s = "beta";
3664
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
3665
    s = "candidate";
3666
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
3667
    s = "final";
3668
#endif
3669
3670
37
#define SetIntItem(flag) \
3671
148
    PyStructSequence_SET_ITEM(version_info, pos++, PyLong_FromLong(flag))
3672
37
#define SetStrItem(flag) \
3673
37
    PyStructSequence_SET_ITEM(version_info, pos++, PyUnicode_FromString(flag))
3674
3675
37
    SetIntItem(PY_MAJOR_VERSION);
3676
37
    SetIntItem(PY_MINOR_VERSION);
3677
37
    SetIntItem(PY_MICRO_VERSION);
3678
37
    SetStrItem(s);
3679
37
    SetIntItem(PY_RELEASE_SERIAL);
3680
37
#undef SetIntItem
3681
37
#undef SetStrItem
3682
3683
37
    if (_PyErr_Occurred(tstate)) {
3684
0
        Py_CLEAR(version_info);
3685
0
        return NULL;
3686
0
    }
3687
37
    return version_info;
3688
37
}
3689
3690
/* sys.implementation values */
3691
#ifndef _PY_IMPL_NAME
3692
#define _PY_IMPL_NAME "cpython"
3693
#endif
3694
const char *_PySys_ImplName = _PY_IMPL_NAME;
3695
#ifndef _PY_IMPL_CACHE_TAG
3696
#define MAJOR Py_STRINGIFY(PY_MAJOR_VERSION)
3697
#define MINOR Py_STRINGIFY(PY_MINOR_VERSION)
3698
#define _PY_IMPL_CACHE_TAG _PY_IMPL_NAME "-" MAJOR MINOR
3699
#endif
3700
const char *_PySys_ImplCacheTag = _PY_IMPL_CACHE_TAG;
3701
#ifdef MAJOR
3702
#undef MAJOR
3703
#endif
3704
#ifdef MINOR
3705
#undef MINOR
3706
#endif
3707
3708
static PyObject *
3709
make_impl_info(PyObject *version_info)
3710
37
{
3711
37
    int res;
3712
37
    PyObject *impl_info, *value, *ns;
3713
3714
37
    impl_info = PyDict_New();
3715
37
    if (impl_info == NULL)
3716
0
        return NULL;
3717
3718
    /* populate the dict */
3719
3720
37
    value = PyUnicode_FromString(_PySys_ImplName);
3721
37
    if (value == NULL)
3722
0
        goto error;
3723
37
    res = PyDict_SetItemString(impl_info, "name", value);
3724
37
    Py_DECREF(value);
3725
37
    if (res < 0)
3726
0
        goto error;
3727
3728
37
    value = _PySys_ImplCacheTag
3729
37
        ? PyUnicode_FromString(_PySys_ImplCacheTag)
3730
37
        : Py_NewRef(Py_None);
3731
37
    if (value == NULL) {
3732
0
        goto error;
3733
0
    }
3734
37
    res = PyDict_SetItemString(impl_info, "cache_tag", value);
3735
37
    Py_DECREF(value);
3736
37
    if (res < 0)
3737
0
        goto error;
3738
3739
37
    res = PyDict_SetItemString(impl_info, "version", version_info);
3740
37
    if (res < 0)
3741
0
        goto error;
3742
3743
37
    value = PyLong_FromLong(PY_VERSION_HEX);
3744
37
    if (value == NULL)
3745
0
        goto error;
3746
37
    res = PyDict_SetItemString(impl_info, "hexversion", value);
3747
37
    Py_DECREF(value);
3748
37
    if (res < 0)
3749
0
        goto error;
3750
3751
37
#ifdef MULTIARCH
3752
37
    value = PyUnicode_FromString(MULTIARCH);
3753
37
    if (value == NULL)
3754
0
        goto error;
3755
37
    res = PyDict_SetItemString(impl_info, "_multiarch", value);
3756
37
    Py_DECREF(value);
3757
37
    if (res < 0)
3758
0
        goto error;
3759
37
#endif
3760
3761
    // PEP-734
3762
#if defined(__wasi__) || defined(__EMSCRIPTEN__)
3763
    // It is not enabled on WASM builds just yet
3764
    value = Py_False;
3765
#else
3766
37
    value = Py_True;
3767
37
#endif
3768
37
    res = PyDict_SetItemString(impl_info, "supports_isolated_interpreters", value);
3769
37
    if (res < 0) {
3770
0
        goto error;
3771
0
    }
3772
3773
    /* dict ready */
3774
3775
37
    ns = _PyNamespace_New(impl_info);
3776
37
    Py_DECREF(impl_info);
3777
37
    return ns;
3778
3779
0
error:
3780
0
    Py_CLEAR(impl_info);
3781
0
    return NULL;
3782
37
}
3783
3784
3785
static PyObject *
3786
make_abi_info(void)
3787
37
{
3788
    // New entries should be added when needed for a supported platform,
3789
    // or by core dev consensus for enabling an unsupported one.
3790
3791
37
    PyObject *value;
3792
37
    PyObject *abi_info = PyDict_New();
3793
37
    if (abi_info == NULL) {
3794
0
        return NULL;
3795
0
    }
3796
3797
37
    value = PyLong_FromLong(sizeof(void *) * 8);
3798
37
    if (value == NULL) {
3799
0
        goto error;
3800
0
    }
3801
37
    if (PyDict_SetItem(abi_info, &_Py_ID(pointer_bits), value) < 0) {
3802
0
        goto error;
3803
0
    }
3804
37
    Py_DECREF(value);
3805
3806
#ifdef Py_GIL_DISABLED
3807
    value = Py_True;
3808
#else
3809
37
    value = Py_False;
3810
37
#endif
3811
37
    if (PyDict_SetItem(abi_info, &_Py_ID(free_threaded), value) < 0) {
3812
0
        goto error;
3813
0
    }
3814
3815
#ifdef Py_DEBUG
3816
    value = Py_True;
3817
#else
3818
37
    value = Py_False;
3819
37
#endif
3820
37
    if (PyDict_SetItem(abi_info, &_Py_ID(debug), value) < 0) {
3821
0
        goto error;
3822
0
    }
3823
3824
#if PY_BIG_ENDIAN
3825
    value = &_Py_ID(big);
3826
#else
3827
37
    value = &_Py_ID(little);
3828
37
#endif
3829
37
    if (PyDict_SetItem(abi_info, &_Py_ID(byteorder), value) < 0) {
3830
0
        goto error;
3831
0
    }
3832
3833
37
    PyObject *ns = _PyNamespace_New(abi_info);
3834
37
    Py_DECREF(abi_info);
3835
37
    return ns;
3836
3837
0
error:
3838
0
    Py_DECREF(abi_info);
3839
0
    Py_XDECREF(value);
3840
0
    return NULL;
3841
37
}
3842
3843
3844
#ifdef __wasi__
3845
3846
static PyObject *
3847
make_wasi_info(void)
3848
{
3849
#if defined(__wasip1__)
3850
    const char *wasi_version = "p1";
3851
#elif defined(__wasip2__)
3852
    const char *wasi_version = "p2";
3853
#elif defined(__wasip3__)
3854
    const char *wasi_version = "p3";
3855
#else
3856
#  error "Unknown WASI target version"
3857
#endif
3858
3859
    // The SDK version is only defined for SDK builds of wasi-libc.
3860
#ifdef __wasi_sdk_version__
3861
    const char *wasi_sdk_version = __wasi_sdk_version__;
3862
#else
3863
#  error "Unknown WASI SDK version"
3864
#endif
3865
3866
#ifdef __wasi_cooperative_threads__
3867
    PyObject *cooperative_threads = Py_True;
3868
#else
3869
    PyObject *cooperative_threads = Py_False;
3870
#endif
3871
3872
    PyObject *wasi_info = Py_BuildValue(
3873
        "{s:s,s:s,s:O}",
3874
        "wasi_version", wasi_version,
3875
        "wasi_sdk_version", wasi_sdk_version,
3876
        "cooperative_threads", cooperative_threads);
3877
    if (wasi_info == NULL) {
3878
        return NULL;
3879
    }
3880
    PyObject *ns = _PyNamespace_New(wasi_info);
3881
    Py_DECREF(wasi_info);
3882
    return ns;
3883
}
3884
3885
#endif // __wasi__
3886
3887
#ifdef __EMSCRIPTEN__
3888
3889
PyDoc_STRVAR(emscripten_info__doc__,
3890
"sys._emscripten_info\n\
3891
\n\
3892
WebAssembly Emscripten platform information.");
3893
3894
static PyTypeObject *EmscriptenInfoType;
3895
3896
static PyStructSequence_Field emscripten_info_fields[] = {
3897
    {"emscripten_version", "Emscripten version (major, minor, micro)"},
3898
    {"runtime", "Runtime (Node.JS version, browser user agent)"},
3899
    {"pthreads", "pthread support"},
3900
    {"shared_memory", "shared memory support"},
3901
    {0}
3902
};
3903
3904
static PyStructSequence_Desc emscripten_info_desc = {
3905
    "sys._emscripten_info",     /* name */
3906
    emscripten_info__doc__ ,    /* doc */
3907
    emscripten_info_fields,     /* fields */
3908
    4
3909
};
3910
3911
EM_JS_DEPS(_Py_emscripten_runtime, "$stringToNewUTF8")
3912
3913
EM_JS(char *, _Py_emscripten_runtime, (void), {
3914
    var info;
3915
    if (typeof process === "object") {
3916
        if (process.versions?.bun) {
3917
            info = `bun v${process.versions.bun}`;
3918
        } else if (process.versions?.deno) {
3919
            info = `deno v${process.versions.deno}`;
3920
        } else {
3921
            // As far as I can tell, every JavaScript runtime puts "node" in
3922
            // process.release.name. Pyodide once checked for
3923
            //
3924
            // process.release.name === "node"
3925
            //
3926
            // and this is apparently part of the reason other runtimes started
3927
            // lying about it. Similar to the situation with userAgent.
3928
            //
3929
            // But just in case some other JS runtime decides to tell us what it
3930
            // is, we'll pick it up.
3931
            const name = process.release?.name ?? "node";
3932
            info = `${name} ${process.version}`;
3933
        }
3934
        // Include v8 version if we know it
3935
        if (process.versions?.v8) {
3936
            info +=  ` (v8 ${process.versions.v8})`;
3937
        }
3938
    } else if (typeof navigator === "object") {
3939
        info = navigator.userAgent;
3940
    } else {
3941
        info = "UNKNOWN";
3942
    }
3943
#if __wasm64__
3944
    return BigInt(stringToNewUTF8(info));
3945
#else
3946
    return stringToNewUTF8(info);
3947
#endif
3948
});
3949
3950
static PyObject *
3951
make_emscripten_info(void)
3952
{
3953
    PyObject *emscripten_info = NULL;
3954
    PyObject *version = NULL;
3955
    char *ua;
3956
    int pos = 0;
3957
3958
    emscripten_info = PyStructSequence_New(EmscriptenInfoType);
3959
    if (emscripten_info == NULL) {
3960
        return NULL;
3961
    }
3962
3963
    version = Py_BuildValue("(iii)",
3964
        __EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__);
3965
    if (version == NULL) {
3966
        goto error;
3967
    }
3968
    PyStructSequence_SET_ITEM(emscripten_info, pos++, version);
3969
3970
    ua = _Py_emscripten_runtime();
3971
    if (ua != NULL) {
3972
        PyObject *oua = PyUnicode_DecodeUTF8(ua, strlen(ua), "strict");
3973
        free(ua);
3974
        if (oua == NULL) {
3975
            goto error;
3976
        }
3977
        PyStructSequence_SET_ITEM(emscripten_info, pos++, oua);
3978
    } else {
3979
        PyStructSequence_SET_ITEM(emscripten_info, pos++, Py_NewRef(Py_None));
3980
    }
3981
3982
#define SetBoolItem(flag) \
3983
    PyStructSequence_SET_ITEM(emscripten_info, pos++, PyBool_FromLong(flag))
3984
3985
#ifdef __EMSCRIPTEN_PTHREADS__
3986
    SetBoolItem(1);
3987
#else
3988
    SetBoolItem(0);
3989
#endif
3990
3991
#ifdef __EMSCRIPTEN_SHARED_MEMORY__
3992
    SetBoolItem(1);
3993
#else
3994
    SetBoolItem(0);
3995
#endif
3996
3997
#undef SetBoolItem
3998
3999
    if (PyErr_Occurred()) {
4000
        goto error;
4001
    }
4002
    return emscripten_info;
4003
4004
  error:
4005
    Py_CLEAR(emscripten_info);
4006
    return NULL;
4007
}
4008
4009
#endif // __EMSCRIPTEN__
4010
4011
static struct PyModuleDef sysmodule = {
4012
    PyModuleDef_HEAD_INIT,
4013
    "sys",
4014
    sys_doc,
4015
    -1, /* multiple "initialization" just copies the module dict. */
4016
    sys_methods,
4017
    NULL,
4018
    NULL,
4019
    NULL,
4020
    NULL
4021
};
4022
4023
/* Updating the sys namespace, returning NULL pointer on error */
4024
#define SET_SYS(key, value)                                \
4025
1.59k
    do {                                                   \
4026
1.59k
        PyObject *v = (value);                             \
4027
1.59k
        if (v == NULL) {                                   \
4028
0
            goto err_occurred;                             \
4029
0
        }                                                  \
4030
1.59k
        res = PyDict_SetItemString(sysdict, key, v);       \
4031
1.59k
        Py_DECREF(v);                                      \
4032
1.59k
        if (res < 0) {                                     \
4033
0
            goto err_occurred;                             \
4034
0
        }                                                  \
4035
1.59k
    } while (0)
4036
4037
#define SET_SYS_FROM_STRING(key, value) \
4038
185
        SET_SYS(key, PyUnicode_FromString(value))
4039
4040
static PyStatus
4041
_PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
4042
37
{
4043
37
    PyObject *version_info;
4044
37
    int res;
4045
37
    PyInterpreterState *interp = tstate->interp;
4046
4047
    /* stdin/stdout/stderr are set in pylifecycle.c */
4048
4049
37
#define COPY_SYS_ATTR(tokey, fromkey) \
4050
148
        SET_SYS(tokey, PyMapping_GetItemString(sysdict, fromkey))
4051
4052
37
    COPY_SYS_ATTR("__displayhook__", "displayhook");
4053
37
    COPY_SYS_ATTR("__excepthook__", "excepthook");
4054
37
    COPY_SYS_ATTR("__breakpointhook__", "breakpointhook");
4055
37
    COPY_SYS_ATTR("__unraisablehook__", "unraisablehook");
4056
4057
37
#undef COPY_SYS_ATTR
4058
4059
37
    SET_SYS_FROM_STRING("version", Py_GetVersion());
4060
37
    SET_SYS("hexversion", PyLong_FromLong(PY_VERSION_HEX));
4061
37
    SET_SYS("_git", Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(),
4062
37
                                  _Py_gitversion()));
4063
37
    SET_SYS_FROM_STRING("_framework", _PYTHONFRAMEWORK);
4064
37
    SET_SYS("api_version", PyLong_FromLong(PYTHON_API_VERSION));
4065
37
    SET_SYS_FROM_STRING("copyright", Py_GetCopyright());
4066
37
    SET_SYS_FROM_STRING("platform", Py_GetPlatform());
4067
37
    SET_SYS("maxsize", PyLong_FromSsize_t(PY_SSIZE_T_MAX));
4068
37
    SET_SYS("float_info", PyFloat_GetInfo());
4069
37
    SET_SYS("int_info", PyLong_GetInfo());
4070
    /* initialize hash_info */
4071
37
    if (_PyStructSequence_InitBuiltin(interp, &Hash_InfoType,
4072
37
                                      &hash_info_desc) < 0)
4073
0
    {
4074
0
        goto type_init_failed;
4075
0
    }
4076
37
    SET_SYS("hash_info", get_hash_info(tstate));
4077
37
    SET_SYS("maxunicode", PyLong_FromLong(0x10FFFF));
4078
37
    SET_SYS("builtin_module_names", list_builtin_module_names());
4079
37
    SET_SYS("stdlib_module_names", list_stdlib_module_names());
4080
#if PY_BIG_ENDIAN
4081
    SET_SYS("byteorder", &_Py_ID(big));
4082
#else
4083
37
    SET_SYS("byteorder", &_Py_ID(little));
4084
37
#endif
4085
4086
#ifdef MS_COREDLL
4087
    SET_SYS("dllhandle", PyLong_FromVoidPtr(PyWin_DLLhModule));
4088
    SET_SYS_FROM_STRING("winver", PyWin_DLLVersionString);
4089
#endif
4090
37
#ifdef ABIFLAGS
4091
37
    SET_SYS_FROM_STRING("abiflags", ABIFLAGS);
4092
37
#endif
4093
4094
37
#define ENSURE_INFO_TYPE(TYPE, DESC) \
4095
74
    do { \
4096
74
        if (_PyStructSequence_InitBuiltinWithFlags( \
4097
74
                interp, &TYPE, &DESC, Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { \
4098
0
            goto type_init_failed; \
4099
0
        } \
4100
74
    } while (0)
4101
4102
    /* version_info */
4103
37
    ENSURE_INFO_TYPE(VersionInfoType, version_info_desc);
4104
37
    version_info = make_version_info(tstate);
4105
37
    SET_SYS("version_info", version_info);
4106
4107
    /* implementation */
4108
37
    SET_SYS("implementation", make_impl_info(version_info));
4109
4110
    // sys.flags: updated later by _PySys_UpdateConfig()
4111
37
    ENSURE_INFO_TYPE(FlagsType, flags_desc);
4112
37
    SET_SYS("flags", make_flags(tstate->interp));
4113
4114
#if defined(MS_WINDOWS)
4115
    /* getwindowsversion */
4116
    ENSURE_INFO_TYPE(WindowsVersionType, windows_version_desc);
4117
4118
    SET_SYS_FROM_STRING("_vpath", VPATH);
4119
#endif
4120
4121
37
#undef ENSURE_INFO_TYPE
4122
4123
    /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */
4124
37
#if _PY_SHORT_FLOAT_REPR == 1
4125
37
    SET_SYS("float_repr_style", &_Py_ID(short));
4126
#else
4127
    SET_SYS("float_repr_style", &_Py_ID(legacy));
4128
#endif
4129
4130
37
    SET_SYS("thread_info", PyThread_GetInfo());
4131
4132
37
    SET_SYS("abi_info", make_abi_info());
4133
4134
#ifdef __wasi__
4135
    SET_SYS("_wasi_info", make_wasi_info());
4136
#endif
4137
4138
    /* initialize asyncgen_hooks */
4139
37
    if (_PyStructSequence_InitBuiltin(interp, &AsyncGenHooksType,
4140
37
                                      &asyncgen_hooks_desc) < 0)
4141
0
    {
4142
0
        goto type_init_failed;
4143
0
    }
4144
4145
#ifdef __EMSCRIPTEN__
4146
    if (EmscriptenInfoType == NULL) {
4147
        EmscriptenInfoType = PyStructSequence_NewType(&emscripten_info_desc);
4148
        if (EmscriptenInfoType == NULL) {
4149
            goto type_init_failed;
4150
        }
4151
    }
4152
    SET_SYS("_emscripten_info", make_emscripten_info());
4153
#endif
4154
4155
    /* adding sys.path_hooks and sys.path_importer_cache */
4156
37
    SET_SYS("meta_path", PyList_New(0));
4157
37
    SET_SYS("path_importer_cache", PyDict_New());
4158
37
    SET_SYS("path_hooks", PyList_New(0));
4159
4160
37
    if (_PyErr_Occurred(tstate)) {
4161
0
        goto err_occurred;
4162
0
    }
4163
37
    return _PyStatus_OK();
4164
4165
0
type_init_failed:
4166
0
    return _PyStatus_ERR("failed to initialize a type");
4167
4168
0
err_occurred:
4169
0
    return _PyStatus_ERR("can't initialize sys module");
4170
37
}
4171
4172
4173
// Update sys attributes for a new PyConfig configuration.
4174
// This function also adds attributes that _PySys_InitCore() didn't add.
4175
int
4176
_PySys_UpdateConfig(PyThreadState *tstate)
4177
37
{
4178
37
    PyInterpreterState *interp = tstate->interp;
4179
37
    PyObject *sysdict = interp->sysdict;
4180
37
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);
4181
37
    int res;
4182
4183
37
#define COPY_LIST(KEY, VALUE) \
4184
148
        SET_SYS(KEY, _PyWideStringList_AsList(&(VALUE)));
4185
4186
37
#define SET_SYS_FROM_WSTR(KEY, VALUE) \
4187
296
        SET_SYS(KEY, PyUnicode_FromWideChar(VALUE, -1));
4188
4189
37
#define COPY_WSTR(SYS_ATTR, WSTR) \
4190
259
    if (WSTR != NULL) { \
4191
259
        SET_SYS_FROM_WSTR(SYS_ATTR, WSTR); \
4192
259
    }
4193
4194
37
    if (config->module_search_paths_set) {
4195
37
        COPY_LIST("path", config->module_search_paths);
4196
37
    }
4197
4198
37
    COPY_WSTR("executable", config->executable);
4199
37
    COPY_WSTR("_base_executable", config->base_executable);
4200
37
    COPY_WSTR("prefix", config->prefix);
4201
37
    COPY_WSTR("base_prefix", config->base_prefix);
4202
37
    COPY_WSTR("exec_prefix", config->exec_prefix);
4203
37
    COPY_WSTR("base_exec_prefix", config->base_exec_prefix);
4204
37
    COPY_WSTR("platlibdir", config->platlibdir);
4205
4206
37
    if (config->pycache_prefix != NULL) {
4207
0
        SET_SYS_FROM_WSTR("pycache_prefix", config->pycache_prefix);
4208
37
    } else {
4209
37
        if (PyDict_SetItemString(sysdict, "pycache_prefix", Py_None) < 0) {
4210
0
            return -1;
4211
0
        }
4212
37
    }
4213
4214
37
    COPY_LIST("argv", config->argv);
4215
37
    COPY_LIST("orig_argv", config->orig_argv);
4216
37
    COPY_LIST("warnoptions", config->warnoptions);
4217
4218
37
    SET_SYS("_xoptions", _PyConfig_CreateXOptionsDict(config));
4219
4220
37
    const wchar_t *stdlibdir = _Py_GetStdlibDir();
4221
37
    if (stdlibdir != NULL) {
4222
37
        SET_SYS_FROM_WSTR("_stdlib_dir", stdlibdir);
4223
37
    }
4224
0
    else {
4225
0
        if (PyDict_SetItemString(sysdict, "_stdlib_dir", Py_None) < 0) {
4226
0
            return -1;
4227
0
        }
4228
0
    }
4229
4230
37
#undef SET_SYS_FROM_WSTR
4231
37
#undef COPY_LIST
4232
37
#undef COPY_WSTR
4233
4234
    // replace sys.flags
4235
37
    PyObject *new_flags = PyStructSequence_New(&FlagsType);
4236
37
    if (new_flags == NULL) {
4237
0
        return -1;
4238
0
    }
4239
37
    if (set_flags_from_config(interp, new_flags) < 0) {
4240
0
        Py_DECREF(new_flags);
4241
0
        return -1;
4242
0
    }
4243
4244
37
    res = _PySys_SetAttr(&_Py_ID(flags), new_flags);
4245
37
    Py_DECREF(new_flags);
4246
37
    if (res < 0) {
4247
0
        return -1;
4248
0
    }
4249
4250
37
    SET_SYS("dont_write_bytecode", PyBool_FromLong(!config->write_bytecode));
4251
4252
37
    if (_PyErr_Occurred(tstate)) {
4253
0
        goto err_occurred;
4254
0
    }
4255
4256
37
    return 0;
4257
4258
0
err_occurred:
4259
0
    return -1;
4260
37
}
4261
4262
#undef SET_SYS
4263
#undef SET_SYS_FROM_STRING
4264
4265
4266
/* Set up a preliminary stderr printer until we have enough
4267
   infrastructure for the io module in place.
4268
4269
   Use UTF-8/backslashreplace and ignore EAGAIN errors. */
4270
static PyStatus
4271
_PySys_SetPreliminaryStderr(PyObject *sysdict)
4272
37
{
4273
37
    PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr));
4274
37
    if (pstderr == NULL) {
4275
0
        goto error;
4276
0
    }
4277
37
    if (PyDict_SetItem(sysdict, &_Py_ID(stderr), pstderr) < 0) {
4278
0
        goto error;
4279
0
    }
4280
37
    if (PyDict_SetItemString(sysdict, "__stderr__", pstderr) < 0) {
4281
0
        goto error;
4282
0
    }
4283
37
    Py_DECREF(pstderr);
4284
37
    return _PyStatus_OK();
4285
4286
0
error:
4287
0
    Py_XDECREF(pstderr);
4288
0
    return _PyStatus_ERR("can't set preliminary stderr");
4289
37
}
4290
4291
PyObject *_Py_CreateMonitoringObject(void);
4292
4293
/*[clinic input]
4294
module _jit
4295
[clinic start generated code]*/
4296
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=10952f74d7bbd972]*/
4297
4298
PyDoc_STRVAR(_jit_doc, "Utilities for observing just-in-time compilation.");
4299
4300
/*[clinic input]
4301
@permit_long_summary
4302
_jit.is_available -> bool
4303
Return True if the current Python executable supports JIT compilation, and False otherwise.
4304
[clinic start generated code]*/
4305
4306
static int
4307
_jit_is_available_impl(PyObject *module)
4308
/*[clinic end generated code: output=6849a9cd2ff4aac9 input=d009d751ae64c9ef]*/
4309
0
{
4310
0
    (void)module;
4311
#ifdef _Py_TIER2
4312
    return true;
4313
#else
4314
0
    return false;
4315
0
#endif
4316
0
}
4317
4318
/*[clinic input]
4319
@permit_long_summary
4320
_jit.is_enabled -> bool
4321
Return True if JIT compilation is enabled for the current Python process (implies sys._jit.is_available()), and False otherwise.
4322
[clinic start generated code]*/
4323
4324
static int
4325
_jit_is_enabled_impl(PyObject *module)
4326
/*[clinic end generated code: output=55865f8de993fe42 input=0524151e857f4f3a]*/
4327
0
{
4328
0
    (void)module;
4329
0
    return _PyInterpreterState_GET()->jit;
4330
0
}
4331
4332
/*[clinic input]
4333
@permit_long_summary
4334
_jit.is_active -> bool
4335
Return True if the topmost Python frame is currently executing JIT code (implies sys._jit.is_enabled()), and False otherwise.
4336
[clinic start generated code]*/
4337
4338
static int
4339
_jit_is_active_impl(PyObject *module)
4340
/*[clinic end generated code: output=7facca06b10064d4 input=081ee32563dc2086]*/
4341
0
{
4342
0
    (void)module;
4343
0
    return _PyThreadState_GET()->current_executor != NULL;
4344
0
}
4345
4346
static PyMethodDef _jit_methods[] = {
4347
    _JIT_IS_AVAILABLE_METHODDEF
4348
    _JIT_IS_ENABLED_METHODDEF
4349
    _JIT_IS_ACTIVE_METHODDEF
4350
    {NULL}
4351
};
4352
4353
static struct PyModuleDef _jit_module = {
4354
    PyModuleDef_HEAD_INIT,
4355
    .m_name = "sys._jit",
4356
    .m_doc = _jit_doc,
4357
    .m_size = -1,
4358
    .m_methods = _jit_methods,
4359
};
4360
4361
/* Create sys module without all attributes.
4362
   _PySys_UpdateConfig() should be called later to add remaining attributes. */
4363
PyStatus
4364
_PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
4365
37
{
4366
37
    assert(!_PyErr_Occurred(tstate));
4367
4368
37
    PyInterpreterState *interp = tstate->interp;
4369
4370
37
    PyObject *modules = _PyImport_InitModules(interp);
4371
37
    if (modules == NULL) {
4372
0
        goto error;
4373
0
    }
4374
4375
37
    PyObject *sysmod = _PyModule_CreateInitialized(&sysmodule, PYTHON_API_VERSION);
4376
37
    if (sysmod == NULL) {
4377
0
        return _PyStatus_ERR("failed to create a module object");
4378
0
    }
4379
#ifdef Py_GIL_DISABLED
4380
    PyUnstable_Module_SetGIL(sysmod, Py_MOD_GIL_NOT_USED);
4381
#endif
4382
4383
37
    PyObject *sysdict = PyModule_GetDict(sysmod);
4384
37
    if (sysdict == NULL) {
4385
0
        goto error;
4386
0
    }
4387
37
    interp->sysdict = Py_NewRef(sysdict);
4388
4389
37
    interp->sysdict_copy = PyDict_Copy(sysdict);
4390
37
    if (interp->sysdict_copy == NULL) {
4391
0
        goto error;
4392
0
    }
4393
4394
37
    if (PyDict_SetItemString(sysdict, "modules", modules) < 0) {
4395
0
        goto error;
4396
0
    }
4397
4398
37
    PyObject *lazy_modules = _PyImport_InitLazyModules(interp); // borrowed reference
4399
37
    if (lazy_modules == NULL) {
4400
0
        goto error;
4401
0
    }
4402
4403
37
    if (PyDict_SetItemString(sysdict, "lazy_modules", lazy_modules) < 0) {
4404
0
        goto error;
4405
0
    }
4406
4407
37
    PyStatus status = _PySys_SetPreliminaryStderr(sysdict);
4408
37
    if (_PyStatus_EXCEPTION(status)) {
4409
0
        return status;
4410
0
    }
4411
4412
37
    status = _PySys_InitCore(tstate, sysdict);
4413
37
    if (_PyStatus_EXCEPTION(status)) {
4414
0
        return status;
4415
0
    }
4416
4417
37
    if (_PyImport_FixupBuiltin(tstate, sysmod, "sys", modules) < 0) {
4418
0
        goto error;
4419
0
    }
4420
4421
37
    PyObject *monitoring = _Py_CreateMonitoringObject();
4422
37
    if (monitoring == NULL) {
4423
0
        goto error;
4424
0
    }
4425
37
    int err = PyDict_SetItemString(sysdict, "monitoring", monitoring);
4426
37
    Py_DECREF(monitoring);
4427
37
    if (err < 0) {
4428
0
        goto error;
4429
0
    }
4430
4431
37
    PyObject *_jit = _PyModule_CreateInitialized(&_jit_module, PYTHON_API_VERSION);
4432
37
    if (_jit == NULL) {
4433
0
        goto error;
4434
0
    }
4435
37
    err = PyDict_SetItemString(sysdict, "_jit", _jit);
4436
37
    Py_DECREF(_jit);
4437
37
    if (err) {
4438
0
        goto error;
4439
0
    }
4440
4441
37
    assert(!_PyErr_Occurred(tstate));
4442
4443
37
    *sysmod_p = sysmod;
4444
37
    return _PyStatus_OK();
4445
4446
0
error:
4447
0
    return _PyStatus_ERR("can't initialize sys module");
4448
37
}
4449
4450
4451
void
4452
_PySys_FiniTypes(PyInterpreterState *interp)
4453
0
{
4454
0
    _PyStructSequence_FiniBuiltin(interp, &VersionInfoType);
4455
0
    _PyStructSequence_FiniBuiltin(interp, &FlagsType);
4456
#if defined(MS_WINDOWS)
4457
    _PyStructSequence_FiniBuiltin(interp, &WindowsVersionType);
4458
#endif
4459
0
    _PyStructSequence_FiniBuiltin(interp, &Hash_InfoType);
4460
0
    _PyStructSequence_FiniBuiltin(interp, &AsyncGenHooksType);
4461
#ifdef __EMSCRIPTEN__
4462
    if (_Py_IsMainInterpreter(interp)) {
4463
        Py_CLEAR(EmscriptenInfoType);
4464
    }
4465
#endif
4466
0
}
4467
4468
4469
static PyObject *
4470
makepathobject(const wchar_t *path, wchar_t delim)
4471
0
{
4472
0
    int i, n;
4473
0
    const wchar_t *p;
4474
0
    PyObject *v, *w;
4475
4476
0
    n = 1;
4477
0
    p = path;
4478
0
    while ((p = wcschr(p, delim)) != NULL) {
4479
0
        n++;
4480
0
        p++;
4481
0
    }
4482
0
    v = PyList_New(n);
4483
0
    if (v == NULL)
4484
0
        return NULL;
4485
0
    for (i = 0; ; i++) {
4486
0
        p = wcschr(path, delim);
4487
0
        if (p == NULL)
4488
0
            p = path + wcslen(path); /* End of string */
4489
0
        w = PyUnicode_FromWideChar(path, (Py_ssize_t)(p - path));
4490
0
        if (w == NULL) {
4491
0
            Py_DECREF(v);
4492
0
            return NULL;
4493
0
        }
4494
0
        PyList_SET_ITEM(v, i, w);
4495
0
        if (*p == '\0')
4496
0
            break;
4497
0
        path = p+1;
4498
0
    }
4499
0
    return v;
4500
0
}
4501
4502
// Removed in Python 3.13 API, but kept for the stable ABI
4503
PyAPI_FUNC(void)
4504
PySys_SetPath(const wchar_t *path)
4505
0
{
4506
0
    PyObject *v;
4507
0
    if ((v = makepathobject(path, DELIM)) == NULL)
4508
0
        Py_FatalError("can't create sys.path");
4509
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
4510
0
    if (sys_set_object(interp, &_Py_ID(path), v) != 0) {
4511
0
        Py_FatalError("can't assign sys.path");
4512
0
    }
4513
0
    Py_DECREF(v);
4514
0
}
4515
4516
static PyObject *
4517
make_sys_argv(int argc, wchar_t * const * argv)
4518
0
{
4519
0
    PyObject *list = PyList_New(argc);
4520
0
    if (list == NULL) {
4521
0
        return NULL;
4522
0
    }
4523
4524
0
    for (Py_ssize_t i = 0; i < argc; i++) {
4525
0
        PyObject *v = PyUnicode_FromWideChar(argv[i], -1);
4526
0
        if (v == NULL) {
4527
0
            Py_DECREF(list);
4528
0
            return NULL;
4529
0
        }
4530
0
        PyList_SET_ITEM(list, i, v);
4531
0
    }
4532
0
    return list;
4533
0
}
4534
4535
// Function removed from Python 3.16 limited C API, but kept in the stable ABI
4536
PyAPI_FUNC(void)
4537
PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
4538
0
{
4539
0
    wchar_t* empty_argv[1] = {L""};
4540
0
    PyThreadState *tstate = _PyThreadState_GET();
4541
4542
0
    if (argc < 1 || argv == NULL) {
4543
        /* Ensure at least one (empty) argument is seen */
4544
0
        argv = empty_argv;
4545
0
        argc = 1;
4546
0
    }
4547
4548
0
    PyObject *av = make_sys_argv(argc, argv);
4549
0
    if (av == NULL) {
4550
0
        Py_FatalError("no mem for sys.argv");
4551
0
    }
4552
0
    if (sys_set_object_str(tstate->interp, "argv", av) != 0) {
4553
0
        Py_DECREF(av);
4554
0
        Py_FatalError("can't assign sys.argv");
4555
0
    }
4556
0
    Py_DECREF(av);
4557
4558
0
    if (updatepath) {
4559
        /* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path.
4560
           If argv[0] is a symlink, use the real path. */
4561
0
        const PyWideStringList argv_list = {.length = argc, .items = argv};
4562
0
        PyObject *path0 = NULL;
4563
0
        if (_PyPathConfig_ComputeSysPath0(&argv_list, &path0)) {
4564
0
            if (path0 == NULL) {
4565
0
                Py_FatalError("can't compute path0 from argv");
4566
0
            }
4567
4568
0
            PyObject *sys_path;
4569
0
            if (PySys_GetOptionalAttr(&_Py_ID(path), &sys_path) < 0) {
4570
0
                Py_FatalError("can't get sys.path");
4571
0
            }
4572
0
            else if (sys_path != NULL) {
4573
0
                if (PyList_Insert(sys_path, 0, path0) < 0) {
4574
0
                    Py_FatalError("can't prepend path0 to sys.path");
4575
0
                }
4576
0
                Py_DECREF(sys_path);
4577
0
            }
4578
0
            Py_DECREF(path0);
4579
0
        }
4580
0
    }
4581
0
}
4582
4583
// Function removed from Python 3.16 limited C API, but kept in the stable ABI
4584
PyAPI_FUNC(void)
4585
PySys_SetArgv(int argc, wchar_t **argv)
4586
0
{
4587
0
    int isolated = 0;
4588
0
    PyThreadState *tstate = PyThreadState_GetUnchecked();
4589
0
    if (tstate != NULL) {
4590
0
        const PyConfig *config = &tstate->interp->config;
4591
0
        isolated = config->isolated;
4592
0
    }
4593
4594
0
    PySys_SetArgvEx(argc, argv, isolated == 0);
4595
0
}
4596
4597
/* Reimplementation of PyFile_WriteString() no calling indirectly
4598
   PyErr_CheckSignals(): avoid the call to PyObject_Str(). */
4599
4600
static int
4601
sys_pyfile_write_unicode(PyObject *unicode, PyObject *file)
4602
0
{
4603
0
    if (file == NULL)
4604
0
        return -1;
4605
0
    assert(unicode != NULL);
4606
0
    PyObject *result = PyObject_CallMethodOneArg(file, &_Py_ID(write), unicode);
4607
0
    if (result == NULL) {
4608
0
        return -1;
4609
0
    }
4610
0
    Py_DECREF(result);
4611
0
    return 0;
4612
0
}
4613
4614
static int
4615
sys_pyfile_write(const char *text, PyObject *file)
4616
0
{
4617
0
    PyObject *unicode = NULL;
4618
0
    int err;
4619
4620
0
    if (file == NULL)
4621
0
        return -1;
4622
4623
0
    unicode = PyUnicode_FromString(text);
4624
0
    if (unicode == NULL)
4625
0
        return -1;
4626
4627
0
    err = sys_pyfile_write_unicode(unicode, file);
4628
0
    Py_DECREF(unicode);
4629
0
    return err;
4630
0
}
4631
4632
/* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
4633
   Adapted from code submitted by Just van Rossum.
4634
4635
   PySys_WriteStdout(format, ...)
4636
   PySys_WriteStderr(format, ...)
4637
4638
      The first function writes to sys.stdout; the second to sys.stderr.  When
4639
      there is a problem, they write to the real (C level) stdout or stderr;
4640
      no exceptions are raised.
4641
4642
      PyErr_CheckSignals() is not called to avoid the execution of the Python
4643
      signal handlers: they may raise a new exception whereas sys_write()
4644
      ignores all exceptions.
4645
4646
      Both take a printf-style format string as their first argument followed
4647
      by a variable length argument list determined by the format string.
4648
4649
      *** WARNING ***
4650
4651
      The format should limit the total size of the formatted output string to
4652
      1000 bytes.  In particular, this means that no unrestricted "%s" formats
4653
      should occur; these should be limited using "%.<N>s where <N> is a
4654
      decimal number calculated so that <N> plus the maximum size of other
4655
      formatted text does not exceed 1000 bytes.  Also watch out for "%f",
4656
      which can print hundreds of digits for very large numbers.
4657
4658
 */
4659
4660
static void
4661
sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
4662
0
{
4663
0
    PyObject *file;
4664
0
    char buffer[1001];
4665
0
    int written;
4666
0
    PyThreadState *tstate = _PyThreadState_GET();
4667
4668
0
    PyObject *exc = _PyErr_GetRaisedException(tstate);
4669
0
    written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
4670
0
    file = PySys_GetAttr(key);
4671
0
    if (sys_pyfile_write(buffer, file) != 0) {
4672
0
        _PyErr_Clear(tstate);
4673
0
        fputs(buffer, fp);
4674
0
    }
4675
0
    if (written < 0 || (size_t)written >= sizeof(buffer)) {
4676
0
        const char *truncated = "... truncated";
4677
0
        if (sys_pyfile_write(truncated, file) != 0)
4678
0
            fputs(truncated, fp);
4679
0
    }
4680
0
    Py_XDECREF(file);
4681
0
    _PyErr_SetRaisedException(tstate, exc);
4682
0
}
4683
4684
void
4685
PySys_WriteStdout(const char *format, ...)
4686
0
{
4687
0
    va_list va;
4688
4689
0
    va_start(va, format);
4690
0
    sys_write(&_Py_ID(stdout), stdout, format, va);
4691
0
    va_end(va);
4692
0
}
4693
4694
void
4695
PySys_WriteStderr(const char *format, ...)
4696
0
{
4697
0
    va_list va;
4698
4699
0
    va_start(va, format);
4700
0
    sys_write(&_Py_ID(stderr), stderr, format, va);
4701
0
    va_end(va);
4702
0
}
4703
4704
void
4705
_PySys_FormatV(PyObject *key, FILE *fp, const char *format, va_list va)
4706
0
{
4707
0
    PyObject *file, *message;
4708
0
    const char *utf8;
4709
0
    PyThreadState *tstate = _PyThreadState_GET();
4710
4711
0
    PyObject *exc = _PyErr_GetRaisedException(tstate);
4712
0
    message = PyUnicode_FromFormatV(format, va);
4713
0
    if (message != NULL) {
4714
0
        file = PySys_GetAttr(key);
4715
0
        if (sys_pyfile_write_unicode(message, file) != 0) {
4716
0
            _PyErr_Clear(tstate);
4717
0
            utf8 = PyUnicode_AsUTF8(message);
4718
0
            if (utf8 != NULL)
4719
0
                fputs(utf8, fp);
4720
0
        }
4721
0
        Py_XDECREF(file);
4722
0
        Py_DECREF(message);
4723
0
    }
4724
0
    _PyErr_SetRaisedException(tstate, exc);
4725
0
}
4726
4727
4728
void
4729
PySys_FormatStdout(const char *format, ...)
4730
0
{
4731
0
    va_list va;
4732
4733
0
    va_start(va, format);
4734
0
    _PySys_FormatV(&_Py_ID(stdout), stdout, format, va);
4735
0
    va_end(va);
4736
0
}
4737
4738
void
4739
PySys_FormatStderr(const char *format, ...)
4740
0
{
4741
0
    va_list va;
4742
4743
0
    va_start(va, format);
4744
0
    _PySys_FormatV(&_Py_ID(stderr), stderr, format, va);
4745
0
    va_end(va);
4746
0
}
4747
4748
4749
int
4750
_PySys_SetIntMaxStrDigits(int maxdigits)
4751
0
{
4752
0
    if (maxdigits != 0 && maxdigits < _PY_LONG_MAX_STR_DIGITS_THRESHOLD) {
4753
0
        PyErr_Format(
4754
0
            PyExc_ValueError, "maxdigits must be >= %d or 0 for unlimited",
4755
0
            _PY_LONG_MAX_STR_DIGITS_THRESHOLD);
4756
0
        return -1;
4757
0
    }
4758
4759
    // Set sys.flags.int_max_str_digits
4760
0
    const Py_ssize_t pos = SYS_FLAGS_INT_MAX_STR_DIGITS;
4761
0
    if (_PySys_SetFlagInt(pos, maxdigits) < 0) {
4762
0
        return -1;
4763
0
    }
4764
4765
    // Set PyInterpreterState.long_state.max_str_digits
4766
    // and PyInterpreterState.config.int_max_str_digits.
4767
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
4768
0
    _Py_atomic_store_int(&interp->long_state.max_str_digits, maxdigits);
4769
0
    _Py_atomic_store_int(&interp->config.int_max_str_digits, maxdigits);
4770
0
    return 0;
4771
0
}