Coverage Report

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