Coverage Report

Created: 2026-05-16 06:46

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
74
{
104
74
    PyThreadState *tstate = _PyThreadState_GET();
105
74
    PyObject *sysdict = tstate->interp->sysdict;
106
74
    if (sysdict == NULL) {
107
0
        PyErr_SetString(PyExc_RuntimeError, "no sys module");
108
0
        return NULL;
109
0
    }
110
74
    PyObject *value;
111
74
    if (PyDict_GetItemStringRef(sysdict, name, &value) == 0) {
112
0
        PyErr_Format(PyExc_RuntimeError, "lost sys.%s", name);
113
0
    }
114
74
    return value;
115
74
}
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
37
{
139
37
    PyThreadState *tstate = _PyThreadState_GET();
140
37
    PyObject *sysdict = tstate->interp->sysdict;
141
37
    if (sysdict == NULL) {
142
0
        *value = NULL;
143
0
        return 0;
144
0
    }
145
37
    return PyDict_GetItemStringRef(sysdict, name, value);
146
37
}
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
222
{
172
222
    if (key == NULL) {
173
0
        return -1;
174
0
    }
175
222
    PyObject *sd = interp->sysdict;
176
222
    if (sd == NULL) {
177
0
        PyErr_SetString(PyExc_RuntimeError, "no sys module");
178
0
        return -1;
179
0
    }
180
222
    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
222
    else {
187
222
        return PyDict_SetItem(sd, key, v);
188
222
    }
189
222
}
190
191
int
192
_PySys_SetAttr(PyObject *key, PyObject *v)
193
111
{
194
111
    PyInterpreterState *interp = _PyInterpreterState_GET();
195
111
    return sys_set_object(interp, key, v);
196
111
}
197
198
static int
199
sys_set_object_str(PyInterpreterState *interp, const char *name, PyObject *v)
200
111
{
201
111
    PyObject *key = v ? PyUnicode_InternFromString(name)
202
111
                      : PyUnicode_FromString(name);
203
111
    int r = sys_set_object(interp, key, v);
204
111
    Py_XDECREF(key);
205
111
    return r;
206
111
}
207
208
int
209
PySys_SetObject(const char *name, PyObject *v)
210
111
{
211
111
    PyInterpreterState *interp = _PyInterpreterState_GET();
212
111
    return sys_set_object_str(interp, name, v);
213
111
}
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.32M
{
233
    /* interp must not be NULL, but test it just in case for extra safety */
234
1.32M
    assert(interp != NULL);
235
1.32M
    if (!interp) {
236
0
        return 0;
237
0
    }
238
1.32M
    return (interp->runtime->audit_hooks.head
239
1.32M
            || interp->audit_hooks
240
742k
            || PyDTrace_AUDIT_ENABLED());
241
1.32M
}
242
243
244
static int
245
sys_audit_tstate(PyThreadState *ts, const char *event,
246
                 const char *argFormat, va_list vargs)
247
1.29M
{
248
1.29M
    assert(event != NULL);
249
1.29M
    assert(!argFormat || !strchr(argFormat, 'N'));
250
251
1.29M
    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.29M
    assert(ts == _PyThreadState_GET());
259
260
    /* Early exit when no hooks are registered */
261
1.29M
    PyInterpreterState *is = ts->interp;
262
1.29M
    if (!should_audit(is)) {
263
730k
        return 0;
264
730k
    }
265
266
563k
    PyObject *eventName = NULL;
267
563k
    PyObject *eventArgs = NULL;
268
563k
    PyObject *hooks = NULL;
269
563k
    PyObject *hook = NULL;
270
563k
    int res = -1;
271
272
563k
    int dtrace = PyDTrace_AUDIT_ENABLED();
273
274
275
563k
    PyObject *exc = _PyErr_GetRaisedException(ts);
276
277
    /* Initialize event args now */
278
563k
    if (argFormat && argFormat[0]) {
279
563k
        eventArgs = Py_VaBuildValue(argFormat, vargs);
280
563k
        if (eventArgs && !PyTuple_Check(eventArgs)) {
281
126k
            PyObject *argTuple = PyTuple_Pack(1, eventArgs);
282
126k
            Py_SETREF(eventArgs, argTuple);
283
126k
        }
284
563k
    }
285
0
    else {
286
0
        eventArgs = PyTuple_New(0);
287
0
    }
288
563k
    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
563k
    _Py_AuditHookEntry *e = is->runtime->audit_hooks.head;
297
563k
    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
563k
    if (dtrace) {
305
0
        PyDTrace_AUDIT(event, (void *)eventArgs);
306
0
    }
307
308
    /* Call interpreter hooks */
309
563k
    if (is->audit_hooks) {
310
563k
        eventName = PyUnicode_FromString(event);
311
563k
        if (!eventName) {
312
0
            goto exit;
313
0
        }
314
315
563k
        hooks = PyObject_GetIter(is->audit_hooks);
316
563k
        if (!hooks) {
317
0
            goto exit;
318
0
        }
319
320
        /* Disallow tracing in hooks unless explicitly enabled */
321
563k
        PyThreadState_EnterTracing(ts);
322
1.12M
        while ((hook = PyIter_Next(hooks)) != NULL) {
323
563k
            PyObject *o;
324
563k
            int canTrace = PyObject_GetOptionalAttr(hook, &_Py_ID(__cantrace__), &o);
325
563k
            if (o) {
326
0
                canTrace = PyObject_IsTrue(o);
327
0
                Py_DECREF(o);
328
0
            }
329
563k
            if (canTrace < 0) {
330
0
                break;
331
0
            }
332
563k
            if (canTrace) {
333
0
                PyThreadState_LeaveTracing(ts);
334
0
            }
335
563k
            PyObject* args[2] = {eventName, eventArgs};
336
563k
            o = _PyObject_VectorcallTstate(ts, hook, args, 2, NULL);
337
563k
            if (canTrace) {
338
0
                PyThreadState_EnterTracing(ts);
339
0
            }
340
563k
            if (!o) {
341
0
                break;
342
0
            }
343
563k
            Py_DECREF(o);
344
563k
            Py_CLEAR(hook);
345
563k
        }
346
563k
        PyThreadState_LeaveTracing(ts);
347
563k
        if (_PyErr_Occurred(ts)) {
348
0
            goto exit;
349
0
        }
350
563k
    }
351
352
563k
    res = 0;
353
354
563k
exit:
355
563k
    Py_XDECREF(hook);
356
563k
    Py_XDECREF(hooks);
357
563k
    Py_XDECREF(eventName);
358
563k
    Py_XDECREF(eventArgs);
359
360
563k
    if (!res) {
361
563k
        _PyErr_SetRaisedException(ts, exc);
362
563k
    }
363
0
    else {
364
0
        assert(_PyErr_Occurred(ts));
365
0
        Py_XDECREF(exc);
366
0
    }
367
368
563k
    return res;
369
563k
}
370
371
int
372
_PySys_Audit(PyThreadState *tstate, const char *event,
373
             const char *argFormat, ...)
374
16.7k
{
375
16.7k
    va_list vargs;
376
16.7k
    va_start(vargs, argFormat);
377
16.7k
    int res = sys_audit_tstate(tstate, event, argFormat, vargs);
378
16.7k
    va_end(vargs);
379
16.7k
    return res;
380
16.7k
}
381
382
int
383
PySys_Audit(const char *event, const char *argFormat, ...)
384
1.27M
{
385
1.27M
    PyThreadState *tstate = _PyThreadState_GET();
386
1.27M
    va_list vargs;
387
1.27M
    va_start(vargs, argFormat);
388
1.27M
    int res = sys_audit_tstate(tstate, event, argFormat, vargs);
389
1.27M
    va_end(vargs);
390
1.27M
    return res;
391
1.27M
}
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
27.8k
{
569
27.8k
    PyThreadState *tstate = _PyThreadState_GET();
570
27.8k
    _Py_EnsureTstateNotNULL(tstate);
571
572
27.8k
    if (!should_audit(tstate->interp)) {
573
11.9k
        Py_RETURN_NONE;
574
11.9k
    }
575
576
15.9k
    int res = _PySys_Audit(tstate, event, "O", args);
577
15.9k
    if (res < 0) {
578
0
        return NULL;
579
0
    }
580
581
15.9k
    Py_RETURN_NONE;
582
15.9k
}
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
78
{
928
78
    _Py_DECLARE_STR(utf_8, "utf-8");
929
78
    PyObject *ret = &_Py_STR(utf_8);
930
78
    return Py_NewRef(ret);
931
78
}
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
78
{
956
78
    PyInterpreterState *interp = _PyInterpreterState_GET();
957
78
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);
958
959
78
    if (wcscmp(config->filesystem_encoding, L"utf-8") == 0) {
960
78
        return get_utf8_unicode();
961
78
    }
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
37
{
981
37
    PyInterpreterState *interp = _PyInterpreterState_GET();
982
37
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);
983
37
    PyObject *u = PyUnicode_FromWideChar(config->filesystem_errors, -1);
984
37
    if (u == NULL) {
985
0
        return NULL;
986
0
    }
987
37
    _PyUnicode_InternImmortal(interp, &u);
988
37
    return u;
989
37
}
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.90k
{
1008
1.90k
    if (PyUnicode_CheckExact(s)) {
1009
1.90k
        PyInterpreterState *interp = _PyInterpreterState_GET();
1010
1.90k
        Py_INCREF(s);
1011
1.90k
        _PyUnicode_InternMortal(interp, &s);
1012
1.90k
        return s;
1013
1.90k
    }
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.90k
}
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
402
{
1358
402
    PyThreadState *tstate = _PyThreadState_GET();
1359
1360
402
    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
402
    int depth = tstate->py_recursion_limit - tstate->py_recursion_remaining;
1369
402
    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
402
    Py_SetRecursionLimit(new_limit);
1378
402
    Py_RETURN_NONE;
1379
402
}
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
37
{
1571
37
    PyObject *hash_info;
1572
37
    int field = 0;
1573
37
    PyHash_FuncDef *hashfunc;
1574
37
    hash_info = PyStructSequence_New(&Hash_InfoType);
1575
37
    if (hash_info == NULL) {
1576
0
        return NULL;
1577
0
    }
1578
37
    hashfunc = PyHash_GetFuncDef();
1579
1580
37
#define SET_HASH_INFO_ITEM(CALL)                             \
1581
333
    do {                                                     \
1582
333
        PyObject *item = (CALL);                             \
1583
333
        if (item == NULL) {                                  \
1584
0
            Py_CLEAR(hash_info);                             \
1585
0
            return NULL;                                     \
1586
0
        }                                                    \
1587
333
        PyStructSequence_SET_ITEM(hash_info, field++, item); \
1588
333
    } while(0)
1589
1590
37
    SET_HASH_INFO_ITEM(PyLong_FromLong(8 * sizeof(Py_hash_t)));
1591
37
    SET_HASH_INFO_ITEM(PyLong_FromSsize_t(PyHASH_MODULUS));
1592
37
    SET_HASH_INFO_ITEM(PyLong_FromLong(PyHASH_INF));
1593
37
    SET_HASH_INFO_ITEM(PyLong_FromLong(0));  // This is no longer used
1594
37
    SET_HASH_INFO_ITEM(PyLong_FromLong(PyHASH_IMAG));
1595
37
    SET_HASH_INFO_ITEM(PyUnicode_FromString(hashfunc->name));
1596
37
    SET_HASH_INFO_ITEM(PyLong_FromLong(hashfunc->hash_bits));
1597
37
    SET_HASH_INFO_ITEM(PyLong_FromLong(hashfunc->seed_bits));
1598
37
    SET_HASH_INFO_ITEM(PyLong_FromLong(Py_HASH_CUTOFF));
1599
1600
37
#undef SET_HASH_INFO_ITEM
1601
1602
37
    return hash_info;
1603
37
}
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
767
{
1618
767
    return PyLong_FromLong(Py_GetRecursionLimit());
1619
767
}
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
sys.get_int_max_str_digits
1867
1868
Return the maximum string digits limit for non-binary int<->str conversions.
1869
[clinic start generated code]*/
1870
1871
static PyObject *
1872
sys_get_int_max_str_digits_impl(PyObject *module)
1873
/*[clinic end generated code: output=0042f5e8ae0e8631 input=61bf9f99bc8b112d]*/
1874
0
{
1875
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
1876
0
    return PyLong_FromLong(interp->long_state.max_str_digits);
1877
0
}
1878
1879
1880
/*[clinic input]
1881
sys.set_int_max_str_digits
1882
1883
    maxdigits: int
1884
1885
Set the maximum string digits limit for non-binary int<->str conversions.
1886
[clinic start generated code]*/
1887
1888
static PyObject *
1889
sys_set_int_max_str_digits_impl(PyObject *module, int maxdigits)
1890
/*[clinic end generated code: output=734d4c2511f2a56d input=d7e3f325db6910c5]*/
1891
0
{
1892
0
    if (_PySys_SetIntMaxStrDigits(maxdigits) < 0) {
1893
0
        return NULL;
1894
0
    }
1895
0
    Py_RETURN_NONE;
1896
0
}
1897
1898
size_t
1899
_PySys_GetSizeOf(PyObject *o)
1900
0
{
1901
0
    PyObject *res = NULL;
1902
0
    PyObject *method;
1903
0
    Py_ssize_t size;
1904
0
    PyThreadState *tstate = _PyThreadState_GET();
1905
1906
    /* Make sure the type is initialized. float gets initialized late */
1907
0
    if (PyType_Ready(Py_TYPE(o)) < 0) {
1908
0
        return (size_t)-1;
1909
0
    }
1910
1911
0
    method = _PyObject_LookupSpecial(o, &_Py_ID(__sizeof__));
1912
0
    if (method == NULL) {
1913
0
        if (!_PyErr_Occurred(tstate)) {
1914
0
            _PyErr_Format(tstate, PyExc_TypeError,
1915
0
                          "Type %.100s doesn't define __sizeof__",
1916
0
                          Py_TYPE(o)->tp_name);
1917
0
        }
1918
0
    }
1919
0
    else {
1920
0
        res = _PyObject_CallNoArgs(method);
1921
0
        Py_DECREF(method);
1922
0
    }
1923
1924
0
    if (res == NULL)
1925
0
        return (size_t)-1;
1926
1927
0
    size = PyLong_AsSsize_t(res);
1928
0
    Py_DECREF(res);
1929
0
    if (size == -1 && _PyErr_Occurred(tstate))
1930
0
        return (size_t)-1;
1931
1932
0
    if (size < 0) {
1933
0
        _PyErr_SetString(tstate, PyExc_ValueError,
1934
0
                          "__sizeof__() should return >= 0");
1935
0
        return (size_t)-1;
1936
0
    }
1937
1938
0
    size_t presize = 0;
1939
0
    if (!Py_IS_TYPE(o, &PyType_Type) ||
1940
0
         PyType_HasFeature((PyTypeObject *)o, Py_TPFLAGS_HEAPTYPE))
1941
0
    {
1942
        /* Add the size of the pre-header if "o" is not a static type */
1943
0
        presize = _PyType_PreHeaderSize(Py_TYPE(o));
1944
0
    }
1945
1946
0
    return (size_t)size + presize;
1947
0
}
1948
1949
static PyObject *
1950
sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
1951
0
{
1952
0
    static char *kwlist[] = {"object", "default", 0};
1953
0
    size_t size;
1954
0
    PyObject *o, *dflt = NULL;
1955
0
    PyThreadState *tstate = _PyThreadState_GET();
1956
1957
0
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof",
1958
0
                                     kwlist, &o, &dflt)) {
1959
0
        return NULL;
1960
0
    }
1961
1962
0
    size = _PySys_GetSizeOf(o);
1963
1964
0
    if (size == (size_t)-1 && _PyErr_Occurred(tstate)) {
1965
        /* Has a default value been given */
1966
0
        if (dflt != NULL && _PyErr_ExceptionMatches(tstate, PyExc_TypeError)) {
1967
0
            _PyErr_Clear(tstate);
1968
0
            return Py_NewRef(dflt);
1969
0
        }
1970
0
        else
1971
0
            return NULL;
1972
0
    }
1973
1974
0
    return PyLong_FromSize_t(size);
1975
0
}
1976
1977
PyDoc_STRVAR(getsizeof_doc,
1978
"getsizeof(object [, default]) -> int\n\
1979
\n\
1980
Return the size of object in bytes.");
1981
1982
/*[clinic input]
1983
sys.getrefcount -> Py_ssize_t
1984
1985
    object:  object
1986
    /
1987
1988
Return the reference count of object.
1989
1990
The count returned is generally one higher than you might expect,
1991
because it includes the (temporary) reference as an argument to
1992
getrefcount().
1993
[clinic start generated code]*/
1994
1995
static Py_ssize_t
1996
sys_getrefcount_impl(PyObject *module, PyObject *object)
1997
/*[clinic end generated code: output=5fd477f2264b85b2 input=bf474efd50a21535]*/
1998
4
{
1999
4
    return Py_REFCNT(object);
2000
4
}
2001
2002
#ifdef Py_REF_DEBUG
2003
/*[clinic input]
2004
sys.gettotalrefcount -> Py_ssize_t
2005
[clinic start generated code]*/
2006
2007
static Py_ssize_t
2008
sys_gettotalrefcount_impl(PyObject *module)
2009
/*[clinic end generated code: output=4103886cf17c25bc input=53b744faa5d2e4f6]*/
2010
{
2011
    /* It may make sense to return the total for the current interpreter
2012
       or have a second function that does so. */
2013
    return _Py_GetGlobalRefTotal();
2014
}
2015
2016
#endif /* Py_REF_DEBUG */
2017
2018
/*[clinic input]
2019
sys.getallocatedblocks -> Py_ssize_t
2020
2021
Return the number of memory blocks currently allocated.
2022
[clinic start generated code]*/
2023
2024
static Py_ssize_t
2025
sys_getallocatedblocks_impl(PyObject *module)
2026
/*[clinic end generated code: output=f0c4e873f0b6dcf7 input=dab13ee346a0673e]*/
2027
0
{
2028
    // It might make sense to return the count
2029
    // for just the current interpreter.
2030
0
    return _Py_GetGlobalAllocatedBlocks();
2031
0
}
2032
2033
/*[clinic input]
2034
sys.getunicodeinternedsize -> Py_ssize_t
2035
2036
    *
2037
    _only_immortal: bool = False
2038
2039
Return the number of elements of the unicode interned dictionary
2040
[clinic start generated code]*/
2041
2042
static Py_ssize_t
2043
sys_getunicodeinternedsize_impl(PyObject *module, int _only_immortal)
2044
/*[clinic end generated code: output=29a6377a94a14f70 input=0330b3408dd5bcc6]*/
2045
0
{
2046
0
    if (_only_immortal) {
2047
0
        return _PyUnicode_InternedSize_Immortal();
2048
0
    }
2049
0
    else {
2050
0
        return _PyUnicode_InternedSize();
2051
0
    }
2052
0
}
2053
2054
/*[clinic input]
2055
sys._getframe
2056
2057
    depth: int = 0
2058
    /
2059
2060
Return a frame object from the call stack.
2061
2062
If optional integer depth is given, return the frame object that many
2063
calls below the top of the stack.  If that is deeper than the call
2064
stack, ValueError is raised.  The default for depth is zero, returning
2065
the frame at the top of the call stack.
2066
2067
This function should be used for internal and specialized purposes
2068
only.
2069
[clinic start generated code]*/
2070
2071
static PyObject *
2072
sys__getframe_impl(PyObject *module, int depth)
2073
/*[clinic end generated code: output=d438776c04d59804 input=c1be8a6464b11ee5]*/
2074
238
{
2075
238
    PyThreadState *tstate = _PyThreadState_GET();
2076
238
    _PyInterpreterFrame *frame = tstate->current_frame;
2077
2078
238
    if (frame != NULL) {
2079
640
        while (depth > 0) {
2080
402
            frame = _PyFrame_GetFirstComplete(frame->previous);
2081
402
            if (frame == NULL) {
2082
0
                break;
2083
0
            }
2084
402
            --depth;
2085
402
        }
2086
238
    }
2087
238
    if (frame == NULL) {
2088
0
        _PyErr_SetString(tstate, PyExc_ValueError,
2089
0
                         "call stack is not deep enough");
2090
0
        return NULL;
2091
0
    }
2092
2093
238
    PyObject *pyFrame = Py_XNewRef((PyObject *)_PyFrame_GetFrameObject(frame));
2094
238
    if (pyFrame && _PySys_Audit(tstate, "sys._getframe", "(O)", pyFrame) < 0) {
2095
0
        Py_DECREF(pyFrame);
2096
0
        return NULL;
2097
0
    }
2098
238
    return pyFrame;
2099
238
}
2100
2101
/*[clinic input]
2102
sys._current_frames
2103
2104
Return a dict mapping each thread's thread id to its current stack frame.
2105
2106
This function should be used for specialized purposes only.
2107
[clinic start generated code]*/
2108
2109
static PyObject *
2110
sys__current_frames_impl(PyObject *module)
2111
/*[clinic end generated code: output=d2a41ac0a0a3809a input=2a9049c5f5033691]*/
2112
0
{
2113
0
    return _PyThread_CurrentFrames();
2114
0
}
2115
2116
/*[clinic input]
2117
@permit_long_summary
2118
sys._current_exceptions
2119
2120
Return a dict mapping each thread's identifier to its current raised exception.
2121
2122
This function should be used for specialized purposes only.
2123
[clinic start generated code]*/
2124
2125
static PyObject *
2126
sys__current_exceptions_impl(PyObject *module)
2127
/*[clinic end generated code: output=2ccfd838c746f0ba input=4ba429b6cfcd736d]*/
2128
0
{
2129
0
    return _PyThread_CurrentExceptions();
2130
0
}
2131
2132
/*[clinic input]
2133
sys.call_tracing
2134
2135
    func: object
2136
    args as funcargs: object(subclass_of='&PyTuple_Type')
2137
    /
2138
2139
Call func(*args), while tracing is enabled.
2140
2141
The tracing state is saved, and restored afterwards.  This is intended
2142
to be called from a debugger from a checkpoint, to recursively debug
2143
some other code.
2144
[clinic start generated code]*/
2145
2146
static PyObject *
2147
sys_call_tracing_impl(PyObject *module, PyObject *func, PyObject *funcargs)
2148
/*[clinic end generated code: output=7e4999853cd4e5a6 input=5102e8b11049f92f]*/
2149
0
{
2150
0
    return _PyEval_CallTracing(func, funcargs);
2151
0
}
2152
2153
/*[clinic input]
2154
sys._debugmallocstats
2155
2156
Print summary info to stderr about the state of pymalloc's structures.
2157
2158
In Py_DEBUG mode, also perform some expensive internal consistency
2159
checks.
2160
[clinic start generated code]*/
2161
2162
static PyObject *
2163
sys__debugmallocstats_impl(PyObject *module)
2164
/*[clinic end generated code: output=ec3565f8c7cee46a input=33c0c9c416f98424]*/
2165
0
{
2166
0
#ifdef WITH_PYMALLOC
2167
0
    if (_PyObject_DebugMallocStats(stderr)) {
2168
0
        fputc('\n', stderr);
2169
0
    }
2170
0
#endif
2171
0
    _PyObject_DebugTypeStats(stderr);
2172
2173
0
    Py_RETURN_NONE;
2174
0
}
2175
2176
#ifdef Py_TRACE_REFS
2177
/* Defined in objects.c because it uses static globals in that file */
2178
extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
2179
#endif
2180
2181
2182
/*[clinic input]
2183
sys._clear_type_cache
2184
2185
Clear the internal type lookup cache.
2186
[clinic start generated code]*/
2187
2188
static PyObject *
2189
sys__clear_type_cache_impl(PyObject *module)
2190
/*[clinic end generated code: output=20e48ca54a6f6971 input=127f3e04a8d9b555]*/
2191
0
{
2192
0
    if (PyErr_WarnEx(PyExc_DeprecationWarning,
2193
0
                     "sys._clear_type_cache() is deprecated and"
2194
0
                     " scheduled for removal in a future version."
2195
0
                     " Use sys._clear_internal_caches() instead.",
2196
0
                     1) < 0)
2197
0
    {
2198
0
        return NULL;
2199
0
    }
2200
0
    PyType_ClearCache();
2201
0
    Py_RETURN_NONE;
2202
0
}
2203
2204
/*[clinic input]
2205
sys._clear_internal_caches
2206
2207
Clear all internal performance-related caches.
2208
[clinic start generated code]*/
2209
2210
static PyObject *
2211
sys__clear_internal_caches_impl(PyObject *module)
2212
/*[clinic end generated code: output=0ee128670a4966d6 input=253e741ca744f6e8]*/
2213
0
{
2214
#ifdef _Py_TIER2
2215
    PyInterpreterState *interp = _PyInterpreterState_GET();
2216
    _Py_Executors_InvalidateAll(interp, 0);
2217
#endif
2218
#ifdef Py_GIL_DISABLED
2219
    if (_Py_ClearUnusedTLBC(_PyInterpreterState_GET()) < 0) {
2220
        return NULL;
2221
    }
2222
#endif
2223
0
    PyType_ClearCache();
2224
0
    Py_RETURN_NONE;
2225
0
}
2226
2227
/* Note that, for now, we do not have a per-interpreter equivalent
2228
  for sys.is_finalizing(). */
2229
2230
/*[clinic input]
2231
sys.is_finalizing
2232
2233
Return True if Python is exiting.
2234
[clinic start generated code]*/
2235
2236
static PyObject *
2237
sys_is_finalizing_impl(PyObject *module)
2238
/*[clinic end generated code: output=735b5ff7962ab281 input=f0df747a039948a5]*/
2239
0
{
2240
0
    return PyBool_FromLong(Py_IsFinalizing());
2241
0
}
2242
2243
2244
#ifdef Py_STATS
2245
/*[clinic input]
2246
sys._stats_on
2247
2248
Turns on stats gathering (stats gathering is off by default).
2249
[clinic start generated code]*/
2250
2251
static PyObject *
2252
sys__stats_on_impl(PyObject *module)
2253
/*[clinic end generated code: output=aca53eafcbb4d9fe input=43b5bfe145299e55]*/
2254
{
2255
    if (_Py_StatsOn() < 0) {
2256
        return NULL;
2257
    }
2258
    Py_RETURN_NONE;
2259
}
2260
2261
/*[clinic input]
2262
sys._stats_off
2263
2264
Turns off stats gathering (stats gathering is off by default).
2265
[clinic start generated code]*/
2266
2267
static PyObject *
2268
sys__stats_off_impl(PyObject *module)
2269
/*[clinic end generated code: output=1534c1ee63812214 input=d1a84c60c56cbce2]*/
2270
{
2271
    _Py_StatsOff();
2272
    Py_RETURN_NONE;
2273
}
2274
2275
/*[clinic input]
2276
sys._stats_clear
2277
2278
Clears the stats.
2279
[clinic start generated code]*/
2280
2281
static PyObject *
2282
sys__stats_clear_impl(PyObject *module)
2283
/*[clinic end generated code: output=fb65a2525ee50604 input=3e03f2654f44da96]*/
2284
{
2285
    _Py_StatsClear();
2286
    Py_RETURN_NONE;
2287
}
2288
2289
/*[clinic input]
2290
@permit_long_docstring_body
2291
sys._stats_dump -> bool
2292
2293
Dump stats to file, and clears the stats.
2294
2295
Return False if no statistics were not dumped because stats gathering was off.
2296
[clinic start generated code]*/
2297
2298
static int
2299
sys__stats_dump_impl(PyObject *module)
2300
/*[clinic end generated code: output=6e346b4ba0de4489 input=5a3ab40d2fb5af47]*/
2301
{
2302
    int res = _Py_PrintSpecializationStats(1);
2303
    _Py_StatsClear();
2304
    return res;
2305
}
2306
#endif   // Py_STATS
2307
2308
2309
#ifdef ANDROID_API_LEVEL
2310
/*[clinic input]
2311
sys.getandroidapilevel
2312
2313
Return the build time API version of Android as an integer.
2314
[clinic start generated code]*/
2315
2316
static PyObject *
2317
sys_getandroidapilevel_impl(PyObject *module)
2318
/*[clinic end generated code: output=214abf183a1c70c1 input=3e6d6c9fcdd24ac6]*/
2319
{
2320
    return PyLong_FromLong(ANDROID_API_LEVEL);
2321
}
2322
#endif   /* ANDROID_API_LEVEL */
2323
2324
/*[clinic input]
2325
sys.activate_stack_trampoline
2326
2327
    backend: str
2328
    /
2329
2330
Activate stack profiler trampoline *backend*.
2331
[clinic start generated code]*/
2332
2333
static PyObject *
2334
sys_activate_stack_trampoline_impl(PyObject *module, const char *backend)
2335
/*[clinic end generated code: output=5783cdeb51874b43 input=a12df928758a82b4]*/
2336
0
{
2337
0
#ifdef PY_HAVE_PERF_TRAMPOLINE
2338
#ifdef _Py_JIT
2339
    if (_PyInterpreterState_GET()->jit) {
2340
        PyErr_SetString(PyExc_ValueError, "Cannot activate the perf trampoline if the JIT is active");
2341
        return NULL;
2342
    }
2343
#endif
2344
2345
0
    if (strcmp(backend, "perf") == 0) {
2346
0
        _PyPerf_Callbacks cur_cb;
2347
0
        _PyPerfTrampoline_GetCallbacks(&cur_cb);
2348
0
        if (cur_cb.write_state != _Py_perfmap_callbacks.write_state) {
2349
0
            if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_callbacks) < 0 ) {
2350
0
                PyErr_SetString(PyExc_ValueError, "can't activate perf trampoline");
2351
0
                return NULL;
2352
0
            }
2353
0
        }
2354
0
    }
2355
0
    else if (strcmp(backend, "perf_jit") == 0) {
2356
0
        _PyPerf_Callbacks cur_cb;
2357
0
        _PyPerfTrampoline_GetCallbacks(&cur_cb);
2358
0
        if (cur_cb.write_state != _Py_perfmap_jit_callbacks.write_state) {
2359
0
            if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_jit_callbacks) < 0 ) {
2360
0
                PyErr_SetString(PyExc_ValueError, "can't activate perf jit trampoline");
2361
0
                return NULL;
2362
0
            }
2363
0
        }
2364
0
    }
2365
0
    else {
2366
0
        PyErr_Format(PyExc_ValueError, "invalid backend: %s", backend);
2367
0
        return NULL;
2368
0
    }
2369
0
    if (_PyPerfTrampoline_Init(1) < 0) {
2370
0
        return NULL;
2371
0
    }
2372
0
    Py_RETURN_NONE;
2373
#else
2374
    PyErr_SetString(PyExc_ValueError, "perf trampoline not available");
2375
    return NULL;
2376
#endif
2377
0
}
2378
2379
2380
/*[clinic input]
2381
sys.deactivate_stack_trampoline
2382
2383
Deactivate the current stack profiler trampoline backend.
2384
2385
If no stack profiler is activated, this function has no effect.
2386
[clinic start generated code]*/
2387
2388
static PyObject *
2389
sys_deactivate_stack_trampoline_impl(PyObject *module)
2390
/*[clinic end generated code: output=b50da25465df0ef1 input=9f629a6be9fe7fc8]*/
2391
0
{
2392
0
    if  (_PyPerfTrampoline_Init(0) < 0) {
2393
0
        return NULL;
2394
0
    }
2395
0
    Py_RETURN_NONE;
2396
0
}
2397
2398
/*[clinic input]
2399
sys.is_stack_trampoline_active
2400
2401
Return *True* if a stack profiler trampoline is active.
2402
[clinic start generated code]*/
2403
2404
static PyObject *
2405
sys_is_stack_trampoline_active_impl(PyObject *module)
2406
/*[clinic end generated code: output=ab2746de0ad9d293 input=29616b7bf6a0b703]*/
2407
0
{
2408
0
#ifdef PY_HAVE_PERF_TRAMPOLINE
2409
0
    if (_PyIsPerfTrampolineActive()) {
2410
0
        Py_RETURN_TRUE;
2411
0
    }
2412
0
#endif
2413
0
    Py_RETURN_FALSE;
2414
0
}
2415
2416
2417
/*[clinic input]
2418
sys.is_remote_debug_enabled
2419
2420
Return True if remote debugging is enabled, False otherwise.
2421
[clinic start generated code]*/
2422
2423
static PyObject *
2424
sys_is_remote_debug_enabled_impl(PyObject *module)
2425
/*[clinic end generated code: output=7ca3d38bdd5935eb input=7335c4a2fe8cf4f3]*/
2426
0
{
2427
#if !defined(Py_REMOTE_DEBUG) || !defined(Py_SUPPORTS_REMOTE_DEBUG)
2428
    Py_RETURN_FALSE;
2429
#else
2430
0
    const PyConfig *config = _Py_GetConfig();
2431
0
    return PyBool_FromLong(config->remote_debug);
2432
0
#endif
2433
0
}
2434
2435
/*[clinic input]
2436
sys.remote_exec
2437
2438
    pid: int
2439
    script: object
2440
2441
Executes a file containing Python code in a given remote Python process.
2442
2443
This function returns immediately, and the code will be executed by the
2444
target process's main thread at the next available opportunity, similarly
2445
to how signals are handled. There is no interface to determine when the
2446
code has been executed. The caller is responsible for making sure that
2447
the file still exists whenever the remote process tries to read it and that
2448
it hasn't been overwritten.
2449
2450
The remote process must be running a CPython interpreter of the same major
2451
and minor version as the local process. If either the local or remote
2452
interpreter is pre-release (alpha, beta, or release candidate) then the
2453
local and remote interpreters must be the same exact version.
2454
2455
Args:
2456
     pid (int): The process ID of the target Python process.
2457
     script (str|bytes): The path to a file containing
2458
         the Python code to be executed.
2459
[clinic start generated code]*/
2460
2461
static PyObject *
2462
sys_remote_exec_impl(PyObject *module, int pid, PyObject *script)
2463
/*[clinic end generated code: output=7d94c56afe4a52c0 input=39908ca2c5fe1eb0]*/
2464
0
{
2465
0
    PyObject *path;
2466
0
    const char *debugger_script_path;
2467
2468
0
    if (PyUnicode_FSConverter(script, &path) == 0) {
2469
0
        return NULL;
2470
0
    }
2471
2472
0
    if (PySys_Audit("sys.remote_exec", "iO", pid, script) < 0) {
2473
0
        goto error;
2474
0
    }
2475
2476
0
    debugger_script_path = PyBytes_AS_STRING(path);
2477
#ifdef MS_WINDOWS
2478
    PyObject *unicode_path;
2479
    if (PyUnicode_FSDecoder(path, &unicode_path) < 0) {
2480
        goto error;
2481
    }
2482
    // Use UTF-16 (wide char) version of the path for permission checks
2483
    wchar_t *debugger_script_path_w = PyUnicode_AsWideCharString(unicode_path, NULL);
2484
    Py_DECREF(unicode_path);
2485
    if (debugger_script_path_w == NULL) {
2486
        goto error;
2487
    }
2488
    DWORD attr = GetFileAttributesW(debugger_script_path_w);
2489
    if (attr == INVALID_FILE_ATTRIBUTES) {
2490
        DWORD err = GetLastError();
2491
        PyMem_Free(debugger_script_path_w);
2492
        if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) {
2493
            PyErr_SetString(PyExc_FileNotFoundError, "Script file does not exist");
2494
        }
2495
        else if (err == ERROR_ACCESS_DENIED) {
2496
            PyErr_SetString(PyExc_PermissionError, "Script file cannot be read");
2497
        }
2498
        else {
2499
            PyErr_SetFromWindowsErr(err);
2500
        }
2501
        goto error;
2502
    }
2503
    PyMem_Free(debugger_script_path_w);
2504
#else // MS_WINDOWS
2505
0
    if (access(debugger_script_path, F_OK | R_OK) != 0) {
2506
0
        switch (errno) {
2507
0
            case ENOENT:
2508
0
                PyErr_SetString(PyExc_FileNotFoundError, "Script file does not exist");
2509
0
                break;
2510
0
            case EACCES:
2511
0
                PyErr_SetString(PyExc_PermissionError, "Script file cannot be read");
2512
0
                break;
2513
0
            default:
2514
0
                PyErr_SetFromErrno(PyExc_OSError);
2515
0
        }
2516
0
        goto error;
2517
0
    }
2518
0
#endif // MS_WINDOWS
2519
0
    if (_PySysRemoteDebug_SendExec(pid, 0, debugger_script_path) < 0) {
2520
0
        goto error;
2521
0
    }
2522
2523
0
    Py_DECREF(path);
2524
0
    Py_RETURN_NONE;
2525
2526
0
error:
2527
0
    Py_DECREF(path);
2528
0
    return NULL;
2529
0
}
2530
2531
2532
2533
/*[clinic input]
2534
sys._dump_tracelets
2535
2536
    outpath: object
2537
2538
Dump the graph of tracelets in graphviz format
2539
[clinic start generated code]*/
2540
2541
static PyObject *
2542
sys__dump_tracelets_impl(PyObject *module, PyObject *outpath)
2543
/*[clinic end generated code: output=a7fe265e2bc3b674 input=5bff6880cd28ffd1]*/
2544
0
{
2545
0
    FILE *out = Py_fopen(outpath, "wb");
2546
0
    if (out == NULL) {
2547
0
        return NULL;
2548
0
    }
2549
0
    int err = _PyDumpExecutors(out);
2550
0
    fclose(out);
2551
0
    if (err) {
2552
0
        return NULL;
2553
0
    }
2554
0
    Py_RETURN_NONE;
2555
0
}
2556
2557
2558
/*[clinic input]
2559
sys._getframemodulename
2560
2561
    depth: int = 0
2562
2563
Return the name of the module for a calling frame.
2564
2565
The default depth returns the module containing the call to this API.
2566
A more typical use in a library will pass a depth of 1 to get the user's
2567
module rather than the library module.
2568
2569
If no frame, module, or name can be found, returns None.
2570
[clinic start generated code]*/
2571
2572
static PyObject *
2573
sys__getframemodulename_impl(PyObject *module, int depth)
2574
/*[clinic end generated code: output=1d70ef691f09d2db input=d4f1a8ed43b8fb46]*/
2575
193
{
2576
193
    if (PySys_Audit("sys._getframemodulename", "i", depth) < 0) {
2577
0
        return NULL;
2578
0
    }
2579
193
    _PyInterpreterFrame *f = _PyThreadState_GET()->current_frame;
2580
394
    while (f && (_PyFrame_IsIncomplete(f) || depth-- > 0)) {
2581
201
        f = f->previous;
2582
201
    }
2583
193
    if (f == NULL || PyStackRef_IsNull(f->f_funcobj)) {
2584
0
        Py_RETURN_NONE;
2585
0
    }
2586
193
    PyObject *func = PyStackRef_AsPyObjectBorrow(f->f_funcobj);
2587
193
    PyObject *r = PyFunction_GetModule(func);
2588
193
    if (!r) {
2589
0
        PyErr_Clear();
2590
0
        r = Py_None;
2591
0
    }
2592
193
    return Py_NewRef(r);
2593
193
}
2594
2595
/*[clinic input]
2596
sys._get_cpu_count_config -> int
2597
2598
Private function for getting PyConfig.cpu_count
2599
[clinic start generated code]*/
2600
2601
static int
2602
sys__get_cpu_count_config_impl(PyObject *module)
2603
/*[clinic end generated code: output=36611bb5efad16dc input=523e1ade2204084e]*/
2604
37
{
2605
37
    const PyConfig *config = _Py_GetConfig();
2606
37
    return config->cpu_count;
2607
37
}
2608
2609
/*[clinic input]
2610
sys._baserepl
2611
2612
Private function for getting the base REPL
2613
[clinic start generated code]*/
2614
2615
static PyObject *
2616
sys__baserepl_impl(PyObject *module)
2617
/*[clinic end generated code: output=f19a36375ebe0a45 input=ade0ebb9fab56f3c]*/
2618
0
{
2619
0
    PyCompilerFlags cf = _PyCompilerFlags_INIT;
2620
0
    PyRun_AnyFileExFlags(stdin, "<stdin>", 0, &cf);
2621
0
    Py_RETURN_NONE;
2622
0
}
2623
2624
2625
/*[clinic input]
2626
sys._is_gil_enabled -> bool
2627
2628
Return True if the GIL is currently enabled and False otherwise.
2629
[clinic start generated code]*/
2630
2631
static int
2632
sys__is_gil_enabled_impl(PyObject *module)
2633
/*[clinic end generated code: output=57732cf53f5b9120 input=7e9c47f15a00e809]*/
2634
0
{
2635
#ifdef Py_GIL_DISABLED
2636
    return _PyEval_IsGILEnabled(_PyThreadState_GET());
2637
#else
2638
0
    return 1;
2639
0
#endif
2640
0
}
2641
2642
2643
#ifndef MS_WINDOWS
2644
static PerfMapState perf_map_state;
2645
#endif
2646
2647
0
PyAPI_FUNC(int) PyUnstable_PerfMapState_Init(void) {
2648
0
#ifndef MS_WINDOWS
2649
0
    char filename[100];
2650
0
    pid_t pid = getpid();
2651
    // Use nofollow flag to prevent symlink attacks.
2652
0
    int flags = O_WRONLY | O_CREAT | O_APPEND | O_NOFOLLOW;
2653
0
#ifdef O_CLOEXEC
2654
0
    flags |= O_CLOEXEC;
2655
0
#endif
2656
0
    snprintf(filename, sizeof(filename) - 1, "/tmp/perf-%jd.map",
2657
0
                (intmax_t)pid);
2658
0
    int fd = open(filename, flags, 0600);
2659
0
    if (fd == -1) {
2660
0
        return -1;
2661
0
    }
2662
0
    else{
2663
0
        perf_map_state.perf_map = fdopen(fd, "a");
2664
0
        if (perf_map_state.perf_map == NULL) {
2665
0
            close(fd);
2666
0
            return -1;
2667
0
        }
2668
0
    }
2669
0
    perf_map_state.map_lock = PyThread_allocate_lock();
2670
0
    if (perf_map_state.map_lock == NULL) {
2671
0
        fclose(perf_map_state.perf_map);
2672
0
        return -2;
2673
0
    }
2674
0
#endif
2675
0
    return 0;
2676
0
}
2677
2678
PyAPI_FUNC(int) PyUnstable_WritePerfMapEntry(
2679
    const void *code_addr,
2680
    size_t code_size,
2681
    const char *entry_name
2682
0
) {
2683
0
#ifndef MS_WINDOWS
2684
0
    if (perf_map_state.perf_map == NULL) {
2685
0
        int ret = PyUnstable_PerfMapState_Init();
2686
0
        if (ret != 0){
2687
0
            return ret;
2688
0
        }
2689
0
    }
2690
0
    PyThread_acquire_lock(perf_map_state.map_lock, 1);
2691
0
    fprintf(perf_map_state.perf_map, "%" PRIxPTR " %zx %s\n", (uintptr_t) code_addr, code_size, entry_name);
2692
0
    fflush(perf_map_state.perf_map);
2693
0
    PyThread_release_lock(perf_map_state.map_lock);
2694
0
#endif
2695
0
    return 0;
2696
0
}
2697
2698
0
PyAPI_FUNC(void) PyUnstable_PerfMapState_Fini(void) {
2699
0
#ifndef MS_WINDOWS
2700
0
    if (perf_map_state.perf_map != NULL) {
2701
        // close the file
2702
0
        PyThread_acquire_lock(perf_map_state.map_lock, 1);
2703
0
        fclose(perf_map_state.perf_map);
2704
0
        PyThread_release_lock(perf_map_state.map_lock);
2705
2706
        // clean up the lock and state
2707
0
        PyThread_free_lock(perf_map_state.map_lock);
2708
0
        perf_map_state.perf_map = NULL;
2709
0
    }
2710
0
#endif
2711
0
}
2712
2713
0
PyAPI_FUNC(int) PyUnstable_CopyPerfMapFile(const char* parent_filename) {
2714
0
#ifndef MS_WINDOWS
2715
0
    if (perf_map_state.perf_map == NULL) {
2716
0
        int ret = PyUnstable_PerfMapState_Init();
2717
0
        if (ret != 0) {
2718
0
            return ret;
2719
0
        }
2720
0
    }
2721
0
    FILE* from = fopen(parent_filename, "r");
2722
0
    if (!from) {
2723
0
        return -1;
2724
0
    }
2725
0
    char buf[4096];
2726
0
    PyThread_acquire_lock(perf_map_state.map_lock, 1);
2727
0
    int result = 0;
2728
0
    while (1) {
2729
0
        size_t bytes_read = fread(buf, 1, sizeof(buf), from);
2730
0
        if (bytes_read == 0) {
2731
0
            if (ferror(from)) {
2732
0
                result = -1;
2733
0
            }
2734
0
            break;
2735
0
        }
2736
2737
0
        size_t bytes_written = fwrite(buf, 1, bytes_read, perf_map_state.perf_map);
2738
0
        if (bytes_written < bytes_read) {
2739
0
            result = -1;
2740
0
            break;
2741
0
        }
2742
2743
0
        if (fflush(perf_map_state.perf_map) != 0) {
2744
0
            result = -1;
2745
0
            break;
2746
0
        }
2747
2748
0
        if (bytes_read < sizeof(buf) && feof(from)) {
2749
0
            break;
2750
0
        }
2751
0
    }
2752
0
    fclose(from);
2753
0
    PyThread_release_lock(perf_map_state.map_lock);
2754
0
    return result;
2755
0
#endif
2756
0
    return 0;
2757
0
}
2758
2759
/*[clinic input]
2760
sys.set_lazy_imports_filter
2761
2762
    filter: object
2763
2764
Set the lazy imports filter callback.
2765
2766
The filter is a callable which disables lazy imports when they
2767
would otherwise be enabled. Returns True if the import is still enabled
2768
or False to disable it. The callable is called with:
2769
2770
(importing_module_name, resolved_imported_module_name, [fromlist])
2771
2772
Pass None to clear the filter.
2773
[clinic start generated code]*/
2774
2775
static PyObject *
2776
sys_set_lazy_imports_filter_impl(PyObject *module, PyObject *filter)
2777
/*[clinic end generated code: output=10251d49469c278c input=fd51ed8df6ab54b7]*/
2778
0
{
2779
0
    if (PyImport_SetLazyImportsFilter(filter) < 0) {
2780
0
        return NULL;
2781
0
    }
2782
2783
0
    Py_RETURN_NONE;
2784
0
}
2785
2786
/*[clinic input]
2787
sys.get_lazy_imports_filter
2788
2789
Get the current lazy imports filter callback.
2790
2791
Returns the filter callable or None if no filter is set.
2792
[clinic start generated code]*/
2793
2794
static PyObject *
2795
sys_get_lazy_imports_filter_impl(PyObject *module)
2796
/*[clinic end generated code: output=3bf73022892165af input=cf1e07cb8e203c94]*/
2797
0
{
2798
0
    PyObject *filter = PyImport_GetLazyImportsFilter();
2799
0
    if (filter == NULL) {
2800
0
        assert(!PyErr_Occurred());
2801
0
        Py_RETURN_NONE;
2802
0
    }
2803
0
    return filter;
2804
0
}
2805
2806
/*[clinic input]
2807
sys.set_lazy_imports
2808
2809
    mode: object
2810
2811
Sets the global lazy imports mode.
2812
2813
The mode parameter must be one of the following strings:
2814
- "all": All top-level imports become potentially lazy
2815
- "none": All lazy imports are suppressed (even explicitly marked ones)
2816
- "normal": Only explicitly marked imports (with 'lazy' keyword) are lazy
2817
2818
In addition to the mode, lazy imports can be controlled via the filter
2819
provided to sys.set_lazy_imports_filter
2820
2821
[clinic start generated code]*/
2822
2823
static PyObject *
2824
sys_set_lazy_imports_impl(PyObject *module, PyObject *mode)
2825
/*[clinic end generated code: output=1ff34ba6c4feaf73 input=f04e70d8bf9fe4f6]*/
2826
0
{
2827
0
    PyImport_LazyImportsMode lazy_mode;
2828
0
    if (!PyUnicode_Check(mode)) {
2829
0
        PyErr_SetString(PyExc_TypeError,
2830
0
                        "mode must be a string: 'normal', 'all', or 'none'");
2831
0
        return NULL;
2832
0
    }
2833
0
    if (PyUnicode_CompareWithASCIIString(mode, "normal") == 0) {
2834
0
        lazy_mode = PyImport_LAZY_NORMAL;
2835
0
    }
2836
0
    else if (PyUnicode_CompareWithASCIIString(mode, "all") == 0) {
2837
0
        lazy_mode = PyImport_LAZY_ALL;
2838
0
    }
2839
0
    else if (PyUnicode_CompareWithASCIIString(mode, "none") == 0) {
2840
0
        lazy_mode = PyImport_LAZY_NONE;
2841
0
    }
2842
0
    else {
2843
0
        PyErr_SetString(PyExc_ValueError,
2844
0
                        "mode must be 'normal', 'all', or 'none'");
2845
0
        return NULL;
2846
0
    }
2847
2848
0
    if (PyImport_SetLazyImportsMode(lazy_mode)) {
2849
0
        return NULL;
2850
0
    }
2851
0
    Py_RETURN_NONE;
2852
0
}
2853
2854
/*[clinic input]
2855
sys.get_lazy_imports
2856
2857
Gets the global lazy imports mode.
2858
2859
Returns "all" if all top level imports are potentially lazy.
2860
Returns "none" if all explicitly marked lazy imports are suppressed.
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=8cb574f1e4e3003c]*/
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
        case PyImport_LAZY_NONE:
2875
0
            return PyUnicode_FromString("none");
2876
0
        default:
2877
0
            PyErr_SetString(PyExc_RuntimeError, "unknown lazy imports mode");
2878
0
            return NULL;
2879
0
    }
2880
0
}
2881
2882
static PyMethodDef sys_methods[] = {
2883
    /* Might as well keep this in alphabetic order */
2884
    SYS_ADDAUDITHOOK_METHODDEF
2885
    SYS_AUDIT_METHODDEF
2886
    {"breakpointhook", _PyCFunction_CAST(sys_breakpointhook),
2887
     METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc},
2888
    SYS__CLEAR_INTERNAL_CACHES_METHODDEF
2889
    SYS__CLEAR_TYPE_CACHE_METHODDEF
2890
    SYS__CURRENT_FRAMES_METHODDEF
2891
    SYS__CURRENT_EXCEPTIONS_METHODDEF
2892
    SYS_DISPLAYHOOK_METHODDEF
2893
    SYS_EXCEPTION_METHODDEF
2894
    SYS_EXC_INFO_METHODDEF
2895
    SYS_EXCEPTHOOK_METHODDEF
2896
    SYS_EXIT_METHODDEF
2897
    SYS_GETDEFAULTENCODING_METHODDEF
2898
    SYS_GETDLOPENFLAGS_METHODDEF
2899
    SYS_GETALLOCATEDBLOCKS_METHODDEF
2900
    SYS_GETUNICODEINTERNEDSIZE_METHODDEF
2901
    SYS_GETFILESYSTEMENCODING_METHODDEF
2902
    SYS_GETFILESYSTEMENCODEERRORS_METHODDEF
2903
#ifdef Py_TRACE_REFS
2904
    {"getobjects", _Py_GetObjects, METH_VARARGS},
2905
#endif
2906
    SYS_GETTOTALREFCOUNT_METHODDEF
2907
    SYS_GETREFCOUNT_METHODDEF
2908
    SYS_GETRECURSIONLIMIT_METHODDEF
2909
    {"getsizeof", _PyCFunction_CAST(sys_getsizeof),
2910
     METH_VARARGS | METH_KEYWORDS, getsizeof_doc},
2911
    SYS__GETFRAME_METHODDEF
2912
    SYS__GETFRAMEMODULENAME_METHODDEF
2913
    SYS_GETWINDOWSVERSION_METHODDEF
2914
    SYS__IS_IMMORTAL_METHODDEF
2915
    SYS_INTERN_METHODDEF
2916
    SYS__IS_INTERNED_METHODDEF
2917
    SYS_IS_FINALIZING_METHODDEF
2918
    SYS_MDEBUG_METHODDEF
2919
    SYS_SETSWITCHINTERVAL_METHODDEF
2920
    SYS_GETSWITCHINTERVAL_METHODDEF
2921
    SYS_SETDLOPENFLAGS_METHODDEF
2922
    SYS_SETPROFILE_METHODDEF
2923
    SYS__SETPROFILEALLTHREADS_METHODDEF
2924
    SYS_GETPROFILE_METHODDEF
2925
    SYS_SETRECURSIONLIMIT_METHODDEF
2926
    SYS_SETTRACE_METHODDEF
2927
    SYS__SETTRACEALLTHREADS_METHODDEF
2928
    SYS_GETTRACE_METHODDEF
2929
    SYS_CALL_TRACING_METHODDEF
2930
    SYS__DEBUGMALLOCSTATS_METHODDEF
2931
    SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF
2932
    SYS_GET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF
2933
    {"set_asyncgen_hooks", _PyCFunction_CAST(sys_set_asyncgen_hooks),
2934
     METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc},
2935
    SYS_GET_ASYNCGEN_HOOKS_METHODDEF
2936
    SYS_GETANDROIDAPILEVEL_METHODDEF
2937
    SYS_ACTIVATE_STACK_TRAMPOLINE_METHODDEF
2938
    SYS_DEACTIVATE_STACK_TRAMPOLINE_METHODDEF
2939
    SYS_IS_STACK_TRAMPOLINE_ACTIVE_METHODDEF
2940
    SYS_IS_REMOTE_DEBUG_ENABLED_METHODDEF
2941
    SYS_REMOTE_EXEC_METHODDEF
2942
    SYS_UNRAISABLEHOOK_METHODDEF
2943
    SYS_GET_INT_MAX_STR_DIGITS_METHODDEF
2944
    SYS_SET_INT_MAX_STR_DIGITS_METHODDEF
2945
    SYS_GET_LAZY_IMPORTS_METHODDEF
2946
    SYS_SET_LAZY_IMPORTS_METHODDEF
2947
    SYS_GET_LAZY_IMPORTS_FILTER_METHODDEF
2948
    SYS_SET_LAZY_IMPORTS_FILTER_METHODDEF
2949
    SYS__BASEREPL_METHODDEF
2950
#ifdef Py_STATS
2951
    SYS__STATS_ON_METHODDEF
2952
    SYS__STATS_OFF_METHODDEF
2953
    SYS__STATS_CLEAR_METHODDEF
2954
    SYS__STATS_DUMP_METHODDEF
2955
#endif
2956
    SYS__GET_CPU_COUNT_CONFIG_METHODDEF
2957
    SYS__IS_GIL_ENABLED_METHODDEF
2958
    SYS__DUMP_TRACELETS_METHODDEF
2959
    {NULL, NULL}  // sentinel
2960
};
2961
2962
2963
static PyObject *
2964
list_builtin_module_names(void)
2965
37
{
2966
37
    PyObject *list = _PyImport_GetBuiltinModuleNames();
2967
37
    if (list == NULL) {
2968
0
        return NULL;
2969
0
    }
2970
37
    if (PyList_Sort(list) != 0) {
2971
0
        goto error;
2972
0
    }
2973
37
    PyObject *tuple = PyList_AsTuple(list);
2974
37
    Py_DECREF(list);
2975
37
    return tuple;
2976
2977
0
error:
2978
0
    Py_DECREF(list);
2979
0
    return NULL;
2980
37
}
2981
2982
2983
static PyObject *
2984
list_stdlib_module_names(void)
2985
37
{
2986
37
    Py_ssize_t len = Py_ARRAY_LENGTH(_Py_stdlib_module_names);
2987
37
    PyObject *names = PyTuple_New(len);
2988
37
    if (names == NULL) {
2989
0
        return NULL;
2990
0
    }
2991
2992
10.9k
    for (Py_ssize_t i = 0; i < len; i++) {
2993
10.9k
        PyObject *name = PyUnicode_FromString(_Py_stdlib_module_names[i]);
2994
10.9k
        if (name == NULL) {
2995
0
            Py_DECREF(names);
2996
0
            return NULL;
2997
0
        }
2998
10.9k
        PyTuple_SET_ITEM(names, i, name);
2999
10.9k
    }
3000
3001
37
    PyObject *set = PyObject_CallFunction((PyObject *)&PyFrozenSet_Type,
3002
37
                                          "(O)", names);
3003
37
    Py_DECREF(names);
3004
37
    return set;
3005
37
}
3006
3007
3008
/* Pre-initialization support for sys.warnoptions and sys._xoptions
3009
 *
3010
 * Modern internal code paths:
3011
 *   These APIs get called after _Py_InitializeCore and get to use the
3012
 *   regular CPython list, dict, and unicode APIs.
3013
 *
3014
 * Legacy embedding code paths:
3015
 *   The multi-phase initialization API isn't public yet, so embedding
3016
 *   apps still need to be able configure sys.warnoptions and sys._xoptions
3017
 *   before they call Py_Initialize. To support this, we stash copies of
3018
 *   the supplied wchar * sequences in linked lists, and then migrate the
3019
 *   contents of those lists to the sys module in _PyInitializeCore.
3020
 *
3021
 */
3022
3023
struct _preinit_entry {
3024
    wchar_t *value;
3025
    struct _preinit_entry *next;
3026
};
3027
3028
typedef struct _preinit_entry *_Py_PreInitEntry;
3029
3030
static _Py_PreInitEntry _preinit_warnoptions = NULL;
3031
static _Py_PreInitEntry _preinit_xoptions = NULL;
3032
3033
static _Py_PreInitEntry
3034
_alloc_preinit_entry(const wchar_t *value)
3035
0
{
3036
    /* To get this to work, we have to initialize the runtime implicitly */
3037
0
    _PyRuntime_Initialize();
3038
3039
    /* Use the default allocator, so we can ensure that it also gets used to
3040
     * destroy the linked list in _clear_preinit_entries.
3041
     */
3042
0
    _Py_PreInitEntry node = _PyMem_DefaultRawCalloc(1, sizeof(*node));
3043
0
    if (node != NULL) {
3044
0
        node->value = _PyMem_DefaultRawWcsdup(value);
3045
0
        if (node->value == NULL) {
3046
0
            _PyMem_DefaultRawFree(node);
3047
0
            node = NULL;
3048
0
        };
3049
0
    };
3050
0
    return node;
3051
0
}
3052
3053
static int
3054
_append_preinit_entry(_Py_PreInitEntry *optionlist, const wchar_t *value)
3055
0
{
3056
0
    _Py_PreInitEntry new_entry = _alloc_preinit_entry(value);
3057
0
    if (new_entry == NULL) {
3058
0
        return -1;
3059
0
    }
3060
    /* We maintain the linked list in this order so it's easy to play back
3061
     * the add commands in the same order later on in _Py_InitializeCore
3062
     */
3063
0
    _Py_PreInitEntry last_entry = *optionlist;
3064
0
    if (last_entry == NULL) {
3065
0
        *optionlist = new_entry;
3066
0
    } else {
3067
0
        while (last_entry->next != NULL) {
3068
0
            last_entry = last_entry->next;
3069
0
        }
3070
0
        last_entry->next = new_entry;
3071
0
    }
3072
0
    return 0;
3073
0
}
3074
3075
static void
3076
_clear_preinit_entries(_Py_PreInitEntry *optionlist)
3077
74
{
3078
74
    _Py_PreInitEntry current = *optionlist;
3079
74
    *optionlist = NULL;
3080
    /* Deallocate the nodes and their contents using the default allocator */
3081
74
    while (current != NULL) {
3082
0
        _Py_PreInitEntry next = current->next;
3083
0
        _PyMem_DefaultRawFree(current->value);
3084
0
        _PyMem_DefaultRawFree(current);
3085
0
        current = next;
3086
0
    }
3087
74
}
3088
3089
3090
PyStatus
3091
_PySys_ReadPreinitWarnOptions(PyWideStringList *options)
3092
37
{
3093
37
    PyStatus status;
3094
37
    _Py_PreInitEntry entry;
3095
3096
37
    for (entry = _preinit_warnoptions; entry != NULL; entry = entry->next) {
3097
0
        status = PyWideStringList_Append(options, entry->value);
3098
0
        if (_PyStatus_EXCEPTION(status)) {
3099
0
            return status;
3100
0
        }
3101
0
    }
3102
3103
37
    _clear_preinit_entries(&_preinit_warnoptions);
3104
37
    return _PyStatus_OK();
3105
37
}
3106
3107
3108
PyStatus
3109
_PySys_ReadPreinitXOptions(PyConfig *config)
3110
37
{
3111
37
    PyStatus status;
3112
37
    _Py_PreInitEntry entry;
3113
3114
37
    for (entry = _preinit_xoptions; entry != NULL; entry = entry->next) {
3115
0
        status = PyWideStringList_Append(&config->xoptions, entry->value);
3116
0
        if (_PyStatus_EXCEPTION(status)) {
3117
0
            return status;
3118
0
        }
3119
0
    }
3120
3121
37
    _clear_preinit_entries(&_preinit_xoptions);
3122
37
    return _PyStatus_OK();
3123
37
}
3124
3125
3126
static PyObject *
3127
get_warnoptions(PyThreadState *tstate)
3128
0
{
3129
0
    PyObject *warnoptions;
3130
0
    if (PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
3131
0
        return NULL;
3132
0
    }
3133
0
    if (warnoptions == NULL || !PyList_Check(warnoptions)) {
3134
        /* PEP432 TODO: we can reach this if warnoptions is NULL in the main
3135
        *  interpreter config. When that happens, we need to properly set
3136
         * the `warnoptions` reference in the main interpreter config as well.
3137
         *
3138
         * For Python 3.7, we shouldn't be able to get here due to the
3139
         * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit
3140
         * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig
3141
         * call optional for embedding applications, thus making this
3142
         * reachable again.
3143
         */
3144
0
        Py_XDECREF(warnoptions);
3145
0
        warnoptions = PyList_New(0);
3146
0
        if (warnoptions == NULL) {
3147
0
            return NULL;
3148
0
        }
3149
0
        if (sys_set_object(tstate->interp, &_Py_ID(warnoptions), warnoptions)) {
3150
0
            Py_DECREF(warnoptions);
3151
0
            return NULL;
3152
0
        }
3153
0
    }
3154
0
    return warnoptions;
3155
0
}
3156
3157
PyAPI_FUNC(void)
3158
PySys_ResetWarnOptions(void)
3159
0
{
3160
0
    PyThreadState *tstate = _PyThreadState_GET();
3161
0
    if (tstate == NULL) {
3162
0
        _clear_preinit_entries(&_preinit_warnoptions);
3163
0
        return;
3164
0
    }
3165
3166
0
    PyObject *warnoptions;
3167
0
    if (PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
3168
0
        PyErr_Clear();
3169
0
        return;
3170
0
    }
3171
0
    if (warnoptions != NULL && PyList_Check(warnoptions)) {
3172
0
        PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
3173
0
    }
3174
0
    Py_XDECREF(warnoptions);
3175
0
}
3176
3177
static int
3178
_PySys_AddWarnOptionWithError(PyThreadState *tstate, PyObject *option)
3179
0
{
3180
0
    assert(tstate != NULL);
3181
0
    PyObject *warnoptions = get_warnoptions(tstate);
3182
0
    if (warnoptions == NULL) {
3183
0
        return -1;
3184
0
    }
3185
0
    if (PyList_Append(warnoptions, option)) {
3186
0
        Py_DECREF(warnoptions);
3187
0
        return -1;
3188
0
    }
3189
0
    Py_DECREF(warnoptions);
3190
0
    return 0;
3191
0
}
3192
3193
// Removed in Python 3.13 API, but kept for the stable ABI
3194
PyAPI_FUNC(void)
3195
PySys_AddWarnOptionUnicode(PyObject *option)
3196
0
{
3197
0
    PyThreadState *tstate = _PyThreadState_GET();
3198
0
    _Py_EnsureTstateNotNULL(tstate);
3199
0
    assert(!_PyErr_Occurred(tstate));
3200
0
    if (_PySys_AddWarnOptionWithError(tstate, option) < 0) {
3201
        /* No return value, therefore clear error state if possible */
3202
0
        _PyErr_Clear(tstate);
3203
0
    }
3204
0
}
3205
3206
// Removed in Python 3.13 API, but kept for the stable ABI
3207
PyAPI_FUNC(void)
3208
PySys_AddWarnOption(const wchar_t *s)
3209
0
{
3210
0
    PyThreadState *tstate = _PyThreadState_GET();
3211
0
    if (tstate == NULL) {
3212
0
        _append_preinit_entry(&_preinit_warnoptions, s);
3213
0
        return;
3214
0
    }
3215
0
    PyObject *unicode;
3216
0
    unicode = PyUnicode_FromWideChar(s, -1);
3217
0
    if (unicode == NULL)
3218
0
        return;
3219
0
_Py_COMP_DIAG_PUSH
3220
0
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
3221
0
    PySys_AddWarnOptionUnicode(unicode);
3222
0
_Py_COMP_DIAG_POP
3223
0
    Py_DECREF(unicode);
3224
0
}
3225
3226
// Removed in Python 3.13 API, but kept for the stable ABI
3227
PyAPI_FUNC(int)
3228
PySys_HasWarnOptions(void)
3229
0
{
3230
0
    PyObject *warnoptions;
3231
0
    if (PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
3232
0
        PyErr_Clear();
3233
0
        return 0;
3234
0
    }
3235
0
    int r = (warnoptions != NULL && PyList_Check(warnoptions) &&
3236
0
             PyList_GET_SIZE(warnoptions) > 0);
3237
0
    Py_XDECREF(warnoptions);
3238
0
    return r;
3239
0
}
3240
3241
static PyObject *
3242
get_xoptions(PyThreadState *tstate)
3243
0
{
3244
0
    PyObject *xoptions;
3245
0
    if (PySys_GetOptionalAttr(&_Py_ID(_xoptions), &xoptions) < 0) {
3246
0
        return NULL;
3247
0
    }
3248
0
    if (xoptions == NULL || !PyDict_Check(xoptions)) {
3249
        /* PEP432 TODO: we can reach this if xoptions is NULL in the main
3250
        *  interpreter config. When that happens, we need to properly set
3251
         * the `xoptions` reference in the main interpreter config as well.
3252
         *
3253
         * For Python 3.7, we shouldn't be able to get here due to the
3254
         * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit
3255
         * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig
3256
         * call optional for embedding applications, thus making this
3257
         * reachable again.
3258
         */
3259
0
        Py_XDECREF(xoptions);
3260
0
        xoptions = PyDict_New();
3261
0
        if (xoptions == NULL) {
3262
0
            return NULL;
3263
0
        }
3264
0
        if (sys_set_object(tstate->interp, &_Py_ID(_xoptions), xoptions)) {
3265
0
            Py_DECREF(xoptions);
3266
0
            return NULL;
3267
0
        }
3268
0
    }
3269
0
    return xoptions;
3270
0
}
3271
3272
static int
3273
_PySys_AddXOptionWithError(const wchar_t *s)
3274
0
{
3275
0
    PyObject *name = NULL, *value = NULL;
3276
3277
0
    PyThreadState *tstate = _PyThreadState_GET();
3278
0
    PyObject *opts = get_xoptions(tstate);
3279
0
    if (opts == NULL) {
3280
0
        goto error;
3281
0
    }
3282
3283
0
    const wchar_t *name_end = wcschr(s, L'=');
3284
0
    if (!name_end) {
3285
0
        name = PyUnicode_FromWideChar(s, -1);
3286
0
        if (name == NULL) {
3287
0
            goto error;
3288
0
        }
3289
0
        value = Py_NewRef(Py_True);
3290
0
    }
3291
0
    else {
3292
0
        name = PyUnicode_FromWideChar(s, name_end - s);
3293
0
        if (name == NULL) {
3294
0
            goto error;
3295
0
        }
3296
0
        value = PyUnicode_FromWideChar(name_end + 1, -1);
3297
0
        if (value == NULL) {
3298
0
            goto error;
3299
0
        }
3300
0
    }
3301
0
    if (PyDict_SetItem(opts, name, value) < 0) {
3302
0
        goto error;
3303
0
    }
3304
0
    Py_DECREF(name);
3305
0
    Py_DECREF(value);
3306
0
    Py_DECREF(opts);
3307
0
    return 0;
3308
3309
0
error:
3310
0
    Py_XDECREF(name);
3311
0
    Py_XDECREF(value);
3312
0
    Py_XDECREF(opts);
3313
0
    return -1;
3314
0
}
3315
3316
// Removed in Python 3.13 API, but kept for the stable ABI
3317
PyAPI_FUNC(void)
3318
PySys_AddXOption(const wchar_t *s)
3319
0
{
3320
0
    PyThreadState *tstate = _PyThreadState_GET();
3321
0
    if (tstate == NULL) {
3322
0
        _append_preinit_entry(&_preinit_xoptions, s);
3323
0
        return;
3324
0
    }
3325
0
    if (_PySys_AddXOptionWithError(s) < 0) {
3326
        /* No return value, therefore clear error state if possible */
3327
0
        _PyErr_Clear(tstate);
3328
0
    }
3329
0
}
3330
3331
PyObject *
3332
PySys_GetXOptions(void)
3333
0
{
3334
0
    PyThreadState *tstate = _PyThreadState_GET();
3335
0
    PyObject *opts = get_xoptions(tstate);
3336
0
    Py_XDECREF(opts);
3337
0
    return opts;
3338
0
}
3339
3340
/* XXX This doc string is too long to be a single string literal in VC++ 5.0.
3341
   Two literals concatenated works just fine.  If you have a K&R compiler
3342
   or other abomination that however *does* understand longer strings,
3343
   get rid of the !!! comment in the middle and the quotes that surround it. */
3344
PyDoc_VAR(sys_doc) =
3345
PyDoc_STR(
3346
"This module provides access to some objects used or maintained by the\n\
3347
interpreter and to functions that interact strongly with the interpreter.\n\
3348
\n\
3349
Dynamic objects:\n\
3350
\n\
3351
argv -- command line arguments; argv[0] is the script pathname if known\n\
3352
path -- module search path; path[0] is the script directory, else ''\n\
3353
modules -- dictionary of loaded modules\n\
3354
\n\
3355
displayhook -- called to show results in an interactive session\n\
3356
excepthook -- called to handle any uncaught exception other than SystemExit\n\
3357
  To customize printing in an interactive session or to install a custom\n\
3358
  top-level exception handler, assign other functions to replace these.\n\
3359
\n\
3360
stdin -- standard input file object; used by input()\n\
3361
stdout -- standard output file object; used by print()\n\
3362
stderr -- standard error object; used for error messages\n\
3363
  By assigning other file objects (or objects that behave like files)\n\
3364
  to these, it is possible to redirect all of the interpreter's I/O.\n\
3365
\n\
3366
last_exc - the last uncaught exception\n\
3367
  Only available in an interactive session after a\n\
3368
  traceback has been printed.\n\
3369
last_type -- type of last uncaught exception\n\
3370
last_value -- value of last uncaught exception\n\
3371
last_traceback -- traceback of last uncaught exception\n\
3372
  These three are the (deprecated) legacy representation of last_exc.\n\
3373
"
3374
)
3375
/* concatenating string here */
3376
PyDoc_STR(
3377
"\n\
3378
Static objects:\n\
3379
\n\
3380
abi_info -- Python ABI information.\n\
3381
builtin_module_names -- tuple of module names built into this interpreter\n\
3382
copyright -- copyright notice pertaining to this interpreter\n\
3383
exec_prefix -- prefix used to find the machine-specific Python library\n\
3384
executable -- absolute path of the executable binary of the Python interpreter\n\
3385
float_info -- a named tuple with information about the float implementation.\n\
3386
float_repr_style -- string indicating the style of repr() output for floats\n\
3387
hash_info -- a named tuple with information about the hash algorithm.\n\
3388
hexversion -- version information encoded as a single integer\n\
3389
implementation -- Python implementation information.\n\
3390
int_info -- a named tuple with information about the int implementation.\n\
3391
maxsize -- the largest supported length of containers.\n\
3392
maxunicode -- the value of the largest Unicode code point\n\
3393
platform -- platform identifier\n\
3394
prefix -- prefix used to find the Python library\n\
3395
thread_info -- a named tuple with information about the thread implementation.\n\
3396
version -- the version of this interpreter as a string\n\
3397
version_info -- version information as a named tuple\n\
3398
"
3399
)
3400
#ifdef MS_COREDLL
3401
/* concatenating string here */
3402
PyDoc_STR(
3403
"dllhandle -- [Windows only] integer handle of the Python DLL\n\
3404
winver -- [Windows only] version number of the Python DLL\n\
3405
"
3406
)
3407
#endif /* MS_COREDLL */
3408
PyDoc_STR(
3409
"__stdin__ -- the original stdin; don't touch!\n\
3410
__stdout__ -- the original stdout; don't touch!\n\
3411
__stderr__ -- the original stderr; don't touch!\n\
3412
__displayhook__ -- the original displayhook; don't touch!\n\
3413
__excepthook__ -- the original excepthook; don't touch!\n\
3414
\n\
3415
Functions:\n\
3416
\n\
3417
displayhook() -- print an object to the screen, and save it in builtins._\n\
3418
excepthook() -- print an exception and its traceback to sys.stderr\n\
3419
exception() -- return the current thread's active exception\n\
3420
exc_info() -- return information about the current thread's active exception\n\
3421
exit() -- exit the interpreter by raising SystemExit\n\
3422
getdlopenflags() -- returns flags to be used for dlopen() calls\n\
3423
getprofile() -- get the global profiling function\n\
3424
getrefcount() -- return the reference count for an object (plus one :-)\n\
3425
getrecursionlimit() -- return the max recursion depth for the interpreter\n\
3426
getsizeof() -- return the size of an object in bytes\n\
3427
gettrace() -- get the global debug tracing function\n\
3428
setdlopenflags() -- set the flags to be used for dlopen() calls\n\
3429
setprofile() -- set the global profiling function\n\
3430
setrecursionlimit() -- set the max recursion depth for the interpreter\n\
3431
settrace() -- set the global debug tracing function\n\
3432
"
3433
)
3434
/* end of sys_doc */ ;
3435
3436
3437
PyDoc_STRVAR(flags__doc__,
3438
"sys.flags\n\
3439
\n\
3440
Flags provided through command line arguments or environment vars.");
3441
3442
static PyTypeObject FlagsType;
3443
3444
static PyStructSequence_Field flags_fields[] = {
3445
    {"debug",                   "-d"},
3446
    {"inspect",                 "-i"},
3447
    {"interactive",             "-i"},
3448
    {"optimize",                "-O or -OO"},
3449
    {"dont_write_bytecode",     "-B"},
3450
    {"no_user_site",            "-s"},
3451
    {"no_site",                 "-S"},
3452
    {"ignore_environment",      "-E"},
3453
    {"verbose",                 "-v"},
3454
    {"bytes_warning",           "-b"},
3455
    {"quiet",                   "-q"},
3456
    {"hash_randomization",      "-R"},
3457
    {"isolated",                "-I"},
3458
    {"dev_mode",                "-X dev"},
3459
    {"utf8_mode",               "-X utf8"},
3460
    {"warn_default_encoding",   "-X warn_default_encoding"},
3461
    {"safe_path",               "-P"},
3462
    {"int_max_str_digits",      "-X int_max_str_digits"},
3463
    // Fields below are only usable by sys.flags attribute name, not index:
3464
    {"gil",                     "-X gil"},
3465
    {"thread_inherit_context",  "-X thread_inherit_context"},
3466
    {"context_aware_warnings",  "-X context_aware_warnings"},
3467
    {"lazy_imports",            "-X lazy_imports"},
3468
    {0}
3469
};
3470
3471
0
#define SYS_FLAGS_INT_MAX_STR_DIGITS 17
3472
3473
static PyStructSequence_Desc flags_desc = {
3474
    "sys.flags",        /* name */
3475
    flags__doc__,       /* doc */
3476
    flags_fields,       /* fields */
3477
    18  /* NB - do not increase beyond 3.13's value of 18. */
3478
    // New sys.flags fields should NOT be tuple addressable per
3479
    // https://github.com/python/cpython/issues/122575#issuecomment-2416497086
3480
};
3481
3482
static void
3483
sys_set_flag(PyObject *flags, Py_ssize_t pos, PyObject *value)
3484
1.62k
{
3485
1.62k
    assert(pos >= 0 && pos < (Py_ssize_t)(Py_ARRAY_LENGTH(flags_fields) - 1));
3486
3487
1.62k
    PyObject *old_value = PyStructSequence_GET_ITEM(flags, pos);
3488
1.62k
    PyStructSequence_SET_ITEM(flags, pos, Py_NewRef(value));
3489
1.62k
    Py_XDECREF(old_value);
3490
1.62k
}
3491
3492
3493
int
3494
_PySys_SetFlagObj(Py_ssize_t pos, PyObject *value)
3495
0
{
3496
0
    PyObject *flags = PySys_GetAttrString("flags");
3497
0
    if (flags == NULL) {
3498
0
        return -1;
3499
0
    }
3500
3501
0
    sys_set_flag(flags, pos, value);
3502
0
    Py_DECREF(flags);
3503
0
    return 0;
3504
0
}
3505
3506
3507
static int
3508
_PySys_SetFlagInt(Py_ssize_t pos, int value)
3509
0
{
3510
0
    PyObject *obj = PyLong_FromLong(value);
3511
0
    if (obj == NULL) {
3512
0
        return -1;
3513
0
    }
3514
3515
0
    int res = _PySys_SetFlagObj(pos, obj);
3516
0
    Py_DECREF(obj);
3517
0
    return res;
3518
0
}
3519
3520
3521
static int
3522
set_flags_from_config(PyInterpreterState *interp, PyObject *flags)
3523
74
{
3524
74
    const PyPreConfig *preconfig = &interp->runtime->preconfig;
3525
74
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);
3526
3527
    // _PySys_UpdateConfig() modifies sys.flags in-place:
3528
    // Py_XDECREF() is needed in this case.
3529
74
    Py_ssize_t pos = 0;
3530
74
#define SetFlagObj(expr) \
3531
1.62k
    do { \
3532
1.62k
        PyObject *value = (expr); \
3533
1.62k
        if (value == NULL) { \
3534
0
            return -1; \
3535
0
        } \
3536
1.62k
        sys_set_flag(flags, pos, value); \
3537
1.62k
        Py_DECREF(value); \
3538
1.62k
        pos++; \
3539
1.62k
    } while (0)
3540
1.40k
#define SetFlag(expr) SetFlagObj(PyLong_FromLong(expr))
3541
3542
74
    SetFlag(config->parser_debug);
3543
74
    SetFlag(config->inspect);
3544
74
    SetFlag(config->interactive);
3545
74
    SetFlag(config->optimization_level);
3546
74
    SetFlag(!config->write_bytecode);
3547
74
    SetFlag(!config->user_site_directory);
3548
74
    SetFlag(!config->site_import);
3549
74
    SetFlag(!config->use_environment);
3550
74
    SetFlag(config->verbose);
3551
74
    SetFlag(config->bytes_warning);
3552
74
    SetFlag(config->quiet);
3553
74
    SetFlag(config->use_hash_seed == 0 || config->hash_seed != 0);
3554
74
    SetFlag(config->isolated);
3555
74
    SetFlagObj(PyBool_FromLong(config->dev_mode));
3556
74
    SetFlag(preconfig->utf8_mode);
3557
74
    SetFlag(config->warn_default_encoding);
3558
74
    SetFlagObj(PyBool_FromLong(config->safe_path));
3559
74
    SetFlag(config->int_max_str_digits);
3560
#ifdef Py_GIL_DISABLED
3561
    if (config->enable_gil == _PyConfig_GIL_DEFAULT) {
3562
        SetFlagObj(Py_NewRef(Py_None));
3563
    }
3564
    else {
3565
        SetFlag(config->enable_gil);
3566
    }
3567
#else
3568
74
    SetFlagObj(PyLong_FromLong(1));
3569
74
#endif
3570
74
    SetFlag(config->thread_inherit_context);
3571
74
    SetFlag(config->context_aware_warnings);
3572
74
    SetFlag(config->lazy_imports);
3573
74
#undef SetFlagObj
3574
74
#undef SetFlag
3575
74
    return 0;
3576
74
}
3577
3578
3579
static PyObject*
3580
make_flags(PyInterpreterState *interp)
3581
37
{
3582
37
    PyObject *flags = PyStructSequence_New(&FlagsType);
3583
37
    if (flags == NULL) {
3584
0
        return NULL;
3585
0
    }
3586
3587
37
    if (set_flags_from_config(interp, flags) < 0) {
3588
0
        Py_DECREF(flags);
3589
0
        return NULL;
3590
0
    }
3591
37
    return flags;
3592
37
}
3593
3594
3595
PyDoc_STRVAR(version_info__doc__,
3596
"sys.version_info\n\
3597
\n\
3598
Version information as a named tuple.");
3599
3600
static PyTypeObject VersionInfoType;
3601
3602
static PyStructSequence_Field version_info_fields[] = {
3603
    {"major", "Major release number"},
3604
    {"minor", "Minor release number"},
3605
    {"micro", "Patch release number"},
3606
    {"releaselevel", "'alpha', 'beta', 'candidate', or 'final'"},
3607
    {"serial", "Serial release number"},
3608
    {0}
3609
};
3610
3611
static PyStructSequence_Desc version_info_desc = {
3612
    "sys.version_info",     /* name */
3613
    version_info__doc__,    /* doc */
3614
    version_info_fields,    /* fields */
3615
    5
3616
};
3617
3618
static PyObject *
3619
make_version_info(PyThreadState *tstate)
3620
37
{
3621
37
    PyObject *version_info;
3622
37
    char *s;
3623
37
    int pos = 0;
3624
3625
37
    version_info = PyStructSequence_New(&VersionInfoType);
3626
37
    if (version_info == NULL) {
3627
0
        return NULL;
3628
0
    }
3629
3630
    /*
3631
     * These release level checks are mutually exclusive and cover
3632
     * the field, so don't get too fancy with the pre-processor!
3633
     */
3634
37
#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
3635
37
    s = "alpha";
3636
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
3637
    s = "beta";
3638
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
3639
    s = "candidate";
3640
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
3641
    s = "final";
3642
#endif
3643
3644
37
#define SetIntItem(flag) \
3645
148
    PyStructSequence_SET_ITEM(version_info, pos++, PyLong_FromLong(flag))
3646
37
#define SetStrItem(flag) \
3647
37
    PyStructSequence_SET_ITEM(version_info, pos++, PyUnicode_FromString(flag))
3648
3649
37
    SetIntItem(PY_MAJOR_VERSION);
3650
37
    SetIntItem(PY_MINOR_VERSION);
3651
37
    SetIntItem(PY_MICRO_VERSION);
3652
37
    SetStrItem(s);
3653
37
    SetIntItem(PY_RELEASE_SERIAL);
3654
37
#undef SetIntItem
3655
37
#undef SetStrItem
3656
3657
37
    if (_PyErr_Occurred(tstate)) {
3658
0
        Py_CLEAR(version_info);
3659
0
        return NULL;
3660
0
    }
3661
37
    return version_info;
3662
37
}
3663
3664
/* sys.implementation values */
3665
#ifndef _PY_IMPL_NAME
3666
#define _PY_IMPL_NAME "cpython"
3667
#endif
3668
const char *_PySys_ImplName = _PY_IMPL_NAME;
3669
#ifndef _PY_IMPL_CACHE_TAG
3670
#define MAJOR Py_STRINGIFY(PY_MAJOR_VERSION)
3671
#define MINOR Py_STRINGIFY(PY_MINOR_VERSION)
3672
#define _PY_IMPL_CACHE_TAG _PY_IMPL_NAME "-" MAJOR MINOR
3673
#endif
3674
const char *_PySys_ImplCacheTag = _PY_IMPL_CACHE_TAG;
3675
#ifdef MAJOR
3676
#undef MAJOR
3677
#endif
3678
#ifdef MINOR
3679
#undef MINOR
3680
#endif
3681
3682
static PyObject *
3683
make_impl_info(PyObject *version_info)
3684
37
{
3685
37
    int res;
3686
37
    PyObject *impl_info, *value, *ns;
3687
3688
37
    impl_info = PyDict_New();
3689
37
    if (impl_info == NULL)
3690
0
        return NULL;
3691
3692
    /* populate the dict */
3693
3694
37
    value = PyUnicode_FromString(_PySys_ImplName);
3695
37
    if (value == NULL)
3696
0
        goto error;
3697
37
    res = PyDict_SetItemString(impl_info, "name", value);
3698
37
    Py_DECREF(value);
3699
37
    if (res < 0)
3700
0
        goto error;
3701
3702
37
    value = _PySys_ImplCacheTag
3703
37
        ? PyUnicode_FromString(_PySys_ImplCacheTag)
3704
37
        : Py_NewRef(Py_None);
3705
37
    if (value == NULL) {
3706
0
        goto error;
3707
0
    }
3708
37
    res = PyDict_SetItemString(impl_info, "cache_tag", value);
3709
37
    Py_DECREF(value);
3710
37
    if (res < 0)
3711
0
        goto error;
3712
3713
37
    res = PyDict_SetItemString(impl_info, "version", version_info);
3714
37
    if (res < 0)
3715
0
        goto error;
3716
3717
37
    value = PyLong_FromLong(PY_VERSION_HEX);
3718
37
    if (value == NULL)
3719
0
        goto error;
3720
37
    res = PyDict_SetItemString(impl_info, "hexversion", value);
3721
37
    Py_DECREF(value);
3722
37
    if (res < 0)
3723
0
        goto error;
3724
3725
37
#ifdef MULTIARCH
3726
37
    value = PyUnicode_FromString(MULTIARCH);
3727
37
    if (value == NULL)
3728
0
        goto error;
3729
37
    res = PyDict_SetItemString(impl_info, "_multiarch", value);
3730
37
    Py_DECREF(value);
3731
37
    if (res < 0)
3732
0
        goto error;
3733
37
#endif
3734
3735
    // PEP-734
3736
#if defined(__wasi__) || defined(__EMSCRIPTEN__)
3737
    // It is not enabled on WASM builds just yet
3738
    value = Py_False;
3739
#else
3740
37
    value = Py_True;
3741
37
#endif
3742
37
    res = PyDict_SetItemString(impl_info, "supports_isolated_interpreters", value);
3743
37
    if (res < 0) {
3744
0
        goto error;
3745
0
    }
3746
3747
    /* dict ready */
3748
3749
37
    ns = _PyNamespace_New(impl_info);
3750
37
    Py_DECREF(impl_info);
3751
37
    return ns;
3752
3753
0
error:
3754
0
    Py_CLEAR(impl_info);
3755
0
    return NULL;
3756
37
}
3757
3758
3759
static PyObject *
3760
make_abi_info(void)
3761
37
{
3762
    // New entries should be added when needed for a supported platform,
3763
    // or by core dev consensus for enabling an unsupported one.
3764
3765
37
    PyObject *value;
3766
37
    PyObject *abi_info = PyDict_New();
3767
37
    if (abi_info == NULL) {
3768
0
        return NULL;
3769
0
    }
3770
3771
37
    value = PyLong_FromLong(sizeof(void *) * 8);
3772
37
    if (value == NULL) {
3773
0
        goto error;
3774
0
    }
3775
37
    if (PyDict_SetItem(abi_info, &_Py_ID(pointer_bits), value) < 0) {
3776
0
        goto error;
3777
0
    }
3778
37
    Py_DECREF(value);
3779
3780
#ifdef Py_GIL_DISABLED
3781
    value = Py_True;
3782
#else
3783
37
    value = Py_False;
3784
37
#endif
3785
37
    if (PyDict_SetItem(abi_info, &_Py_ID(free_threaded), value) < 0) {
3786
0
        goto error;
3787
0
    }
3788
3789
#ifdef Py_DEBUG
3790
    value = Py_True;
3791
#else
3792
37
    value = Py_False;
3793
37
#endif
3794
37
    if (PyDict_SetItem(abi_info, &_Py_ID(debug), value) < 0) {
3795
0
        goto error;
3796
0
    }
3797
3798
#if PY_BIG_ENDIAN
3799
    value = &_Py_ID(big);
3800
#else
3801
37
    value = &_Py_ID(little);
3802
37
#endif
3803
37
    if (PyDict_SetItem(abi_info, &_Py_ID(byteorder), value) < 0) {
3804
0
        goto error;
3805
0
    }
3806
3807
37
    PyObject *ns = _PyNamespace_New(abi_info);
3808
37
    Py_DECREF(abi_info);
3809
37
    return ns;
3810
3811
0
error:
3812
0
    Py_DECREF(abi_info);
3813
0
    Py_XDECREF(value);
3814
0
    return NULL;
3815
37
}
3816
3817
3818
#ifdef __EMSCRIPTEN__
3819
3820
PyDoc_STRVAR(emscripten_info__doc__,
3821
"sys._emscripten_info\n\
3822
\n\
3823
WebAssembly Emscripten platform information.");
3824
3825
static PyTypeObject *EmscriptenInfoType;
3826
3827
static PyStructSequence_Field emscripten_info_fields[] = {
3828
    {"emscripten_version", "Emscripten version (major, minor, micro)"},
3829
    {"runtime", "Runtime (Node.JS version, browser user agent)"},
3830
    {"pthreads", "pthread support"},
3831
    {"shared_memory", "shared memory support"},
3832
    {0}
3833
};
3834
3835
static PyStructSequence_Desc emscripten_info_desc = {
3836
    "sys._emscripten_info",     /* name */
3837
    emscripten_info__doc__ ,    /* doc */
3838
    emscripten_info_fields,     /* fields */
3839
    4
3840
};
3841
3842
EM_JS(char *, _Py_emscripten_runtime, (void), {
3843
    var info;
3844
    if (typeof process === "object") {
3845
        if (process.versions?.bun) {
3846
            info = `bun v${process.versions.bun}`;
3847
        } else if (process.versions?.deno) {
3848
            info = `deno v${process.versions.deno}`;
3849
        } else {
3850
            // As far as I can tell, every JavaScript runtime puts "node" in
3851
            // process.release.name. Pyodide once checked for
3852
            //
3853
            // process.release.name === "node"
3854
            //
3855
            // and this is apparently part of the reason other runtimes started
3856
            // lying about it. Similar to the situation with userAgent.
3857
            //
3858
            // But just in case some other JS runtime decides to tell us what it
3859
            // is, we'll pick it up.
3860
            const name = process.release?.name ?? "node";
3861
            info = `${name} ${process.version}`;
3862
        }
3863
        // Include v8 version if we know it
3864
        if (process.versions?.v8) {
3865
            info +=  ` (v8 ${process.versions.v8})`;
3866
        }
3867
    } else if (typeof navigator === "object") {
3868
        info = navigator.userAgent;
3869
    } else {
3870
        info = "UNKNOWN";
3871
    }
3872
#if __wasm64__
3873
    return BigInt(stringToNewUTF8(info));
3874
#else
3875
    return stringToNewUTF8(info);
3876
#endif
3877
});
3878
3879
static PyObject *
3880
make_emscripten_info(void)
3881
{
3882
    PyObject *emscripten_info = NULL;
3883
    PyObject *version = NULL;
3884
    char *ua;
3885
    int pos = 0;
3886
3887
    emscripten_info = PyStructSequence_New(EmscriptenInfoType);
3888
    if (emscripten_info == NULL) {
3889
        return NULL;
3890
    }
3891
3892
    version = Py_BuildValue("(iii)",
3893
        __EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__);
3894
    if (version == NULL) {
3895
        goto error;
3896
    }
3897
    PyStructSequence_SET_ITEM(emscripten_info, pos++, version);
3898
3899
    ua = _Py_emscripten_runtime();
3900
    if (ua != NULL) {
3901
        PyObject *oua = PyUnicode_DecodeUTF8(ua, strlen(ua), "strict");
3902
        free(ua);
3903
        if (oua == NULL) {
3904
            goto error;
3905
        }
3906
        PyStructSequence_SET_ITEM(emscripten_info, pos++, oua);
3907
    } else {
3908
        PyStructSequence_SET_ITEM(emscripten_info, pos++, Py_NewRef(Py_None));
3909
    }
3910
3911
#define SetBoolItem(flag) \
3912
    PyStructSequence_SET_ITEM(emscripten_info, pos++, PyBool_FromLong(flag))
3913
3914
#ifdef __EMSCRIPTEN_PTHREADS__
3915
    SetBoolItem(1);
3916
#else
3917
    SetBoolItem(0);
3918
#endif
3919
3920
#ifdef __EMSCRIPTEN_SHARED_MEMORY__
3921
    SetBoolItem(1);
3922
#else
3923
    SetBoolItem(0);
3924
#endif
3925
3926
#undef SetBoolItem
3927
3928
    if (PyErr_Occurred()) {
3929
        goto error;
3930
    }
3931
    return emscripten_info;
3932
3933
  error:
3934
    Py_CLEAR(emscripten_info);
3935
    return NULL;
3936
}
3937
3938
#endif // __EMSCRIPTEN__
3939
3940
static struct PyModuleDef sysmodule = {
3941
    PyModuleDef_HEAD_INIT,
3942
    "sys",
3943
    sys_doc,
3944
    -1, /* multiple "initialization" just copies the module dict. */
3945
    sys_methods,
3946
    NULL,
3947
    NULL,
3948
    NULL,
3949
    NULL
3950
};
3951
3952
/* Updating the sys namespace, returning NULL pointer on error */
3953
#define SET_SYS(key, value)                                \
3954
1.59k
    do {                                                   \
3955
1.59k
        PyObject *v = (value);                             \
3956
1.59k
        if (v == NULL) {                                   \
3957
0
            goto err_occurred;                             \
3958
0
        }                                                  \
3959
1.59k
        res = PyDict_SetItemString(sysdict, key, v);       \
3960
1.59k
        Py_DECREF(v);                                      \
3961
1.59k
        if (res < 0) {                                     \
3962
0
            goto err_occurred;                             \
3963
0
        }                                                  \
3964
1.59k
    } while (0)
3965
3966
#define SET_SYS_FROM_STRING(key, value) \
3967
185
        SET_SYS(key, PyUnicode_FromString(value))
3968
3969
static PyStatus
3970
_PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
3971
37
{
3972
37
    PyObject *version_info;
3973
37
    int res;
3974
37
    PyInterpreterState *interp = tstate->interp;
3975
3976
    /* stdin/stdout/stderr are set in pylifecycle.c */
3977
3978
37
#define COPY_SYS_ATTR(tokey, fromkey) \
3979
148
        SET_SYS(tokey, PyMapping_GetItemString(sysdict, fromkey))
3980
3981
37
    COPY_SYS_ATTR("__displayhook__", "displayhook");
3982
37
    COPY_SYS_ATTR("__excepthook__", "excepthook");
3983
37
    COPY_SYS_ATTR("__breakpointhook__", "breakpointhook");
3984
37
    COPY_SYS_ATTR("__unraisablehook__", "unraisablehook");
3985
3986
37
#undef COPY_SYS_ATTR
3987
3988
37
    SET_SYS_FROM_STRING("version", Py_GetVersion());
3989
37
    SET_SYS("hexversion", PyLong_FromLong(PY_VERSION_HEX));
3990
37
    SET_SYS("_git", Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(),
3991
37
                                  _Py_gitversion()));
3992
37
    SET_SYS_FROM_STRING("_framework", _PYTHONFRAMEWORK);
3993
37
    SET_SYS("api_version", PyLong_FromLong(PYTHON_API_VERSION));
3994
37
    SET_SYS_FROM_STRING("copyright", Py_GetCopyright());
3995
37
    SET_SYS_FROM_STRING("platform", Py_GetPlatform());
3996
37
    SET_SYS("maxsize", PyLong_FromSsize_t(PY_SSIZE_T_MAX));
3997
37
    SET_SYS("float_info", PyFloat_GetInfo());
3998
37
    SET_SYS("int_info", PyLong_GetInfo());
3999
    /* initialize hash_info */
4000
37
    if (_PyStructSequence_InitBuiltin(interp, &Hash_InfoType,
4001
37
                                      &hash_info_desc) < 0)
4002
0
    {
4003
0
        goto type_init_failed;
4004
0
    }
4005
37
    SET_SYS("hash_info", get_hash_info(tstate));
4006
37
    SET_SYS("maxunicode", PyLong_FromLong(0x10FFFF));
4007
37
    SET_SYS("builtin_module_names", list_builtin_module_names());
4008
37
    SET_SYS("stdlib_module_names", list_stdlib_module_names());
4009
#if PY_BIG_ENDIAN
4010
    SET_SYS("byteorder", &_Py_ID(big));
4011
#else
4012
37
    SET_SYS("byteorder", &_Py_ID(little));
4013
37
#endif
4014
4015
#ifdef MS_COREDLL
4016
    SET_SYS("dllhandle", PyLong_FromVoidPtr(PyWin_DLLhModule));
4017
    SET_SYS_FROM_STRING("winver", PyWin_DLLVersionString);
4018
#endif
4019
37
#ifdef ABIFLAGS
4020
37
    SET_SYS_FROM_STRING("abiflags", ABIFLAGS);
4021
37
#endif
4022
4023
37
#define ENSURE_INFO_TYPE(TYPE, DESC) \
4024
74
    do { \
4025
74
        if (_PyStructSequence_InitBuiltinWithFlags( \
4026
74
                interp, &TYPE, &DESC, Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { \
4027
0
            goto type_init_failed; \
4028
0
        } \
4029
74
    } while (0)
4030
4031
    /* version_info */
4032
37
    ENSURE_INFO_TYPE(VersionInfoType, version_info_desc);
4033
37
    version_info = make_version_info(tstate);
4034
37
    SET_SYS("version_info", version_info);
4035
4036
    /* implementation */
4037
37
    SET_SYS("implementation", make_impl_info(version_info));
4038
4039
    // sys.flags: updated in-place later by _PySys_UpdateConfig()
4040
37
    ENSURE_INFO_TYPE(FlagsType, flags_desc);
4041
37
    SET_SYS("flags", make_flags(tstate->interp));
4042
4043
#if defined(MS_WINDOWS)
4044
    /* getwindowsversion */
4045
    ENSURE_INFO_TYPE(WindowsVersionType, windows_version_desc);
4046
4047
    SET_SYS_FROM_STRING("_vpath", VPATH);
4048
#endif
4049
4050
37
#undef ENSURE_INFO_TYPE
4051
4052
    /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */
4053
37
#if _PY_SHORT_FLOAT_REPR == 1
4054
37
    SET_SYS("float_repr_style", &_Py_ID(short));
4055
#else
4056
    SET_SYS("float_repr_style", &_Py_ID(legacy));
4057
#endif
4058
4059
37
    SET_SYS("thread_info", PyThread_GetInfo());
4060
4061
37
    SET_SYS("abi_info", make_abi_info());
4062
4063
    /* initialize asyncgen_hooks */
4064
37
    if (_PyStructSequence_InitBuiltin(interp, &AsyncGenHooksType,
4065
37
                                      &asyncgen_hooks_desc) < 0)
4066
0
    {
4067
0
        goto type_init_failed;
4068
0
    }
4069
4070
#ifdef __EMSCRIPTEN__
4071
    if (EmscriptenInfoType == NULL) {
4072
        EmscriptenInfoType = PyStructSequence_NewType(&emscripten_info_desc);
4073
        if (EmscriptenInfoType == NULL) {
4074
            goto type_init_failed;
4075
        }
4076
    }
4077
    SET_SYS("_emscripten_info", make_emscripten_info());
4078
#endif
4079
4080
    /* adding sys.path_hooks and sys.path_importer_cache */
4081
37
    SET_SYS("meta_path", PyList_New(0));
4082
37
    SET_SYS("path_importer_cache", PyDict_New());
4083
37
    SET_SYS("path_hooks", PyList_New(0));
4084
4085
37
    if (_PyErr_Occurred(tstate)) {
4086
0
        goto err_occurred;
4087
0
    }
4088
37
    return _PyStatus_OK();
4089
4090
0
type_init_failed:
4091
0
    return _PyStatus_ERR("failed to initialize a type");
4092
4093
0
err_occurred:
4094
0
    return _PyStatus_ERR("can't initialize sys module");
4095
37
}
4096
4097
4098
// Update sys attributes for a new PyConfig configuration.
4099
// This function also adds attributes that _PySys_InitCore() didn't add.
4100
int
4101
_PySys_UpdateConfig(PyThreadState *tstate)
4102
37
{
4103
37
    PyInterpreterState *interp = tstate->interp;
4104
37
    PyObject *sysdict = interp->sysdict;
4105
37
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);
4106
37
    int res;
4107
4108
37
#define COPY_LIST(KEY, VALUE) \
4109
148
        SET_SYS(KEY, _PyWideStringList_AsList(&(VALUE)));
4110
4111
37
#define SET_SYS_FROM_WSTR(KEY, VALUE) \
4112
296
        SET_SYS(KEY, PyUnicode_FromWideChar(VALUE, -1));
4113
4114
37
#define COPY_WSTR(SYS_ATTR, WSTR) \
4115
259
    if (WSTR != NULL) { \
4116
259
        SET_SYS_FROM_WSTR(SYS_ATTR, WSTR); \
4117
259
    }
4118
4119
37
    if (config->module_search_paths_set) {
4120
37
        COPY_LIST("path", config->module_search_paths);
4121
37
    }
4122
4123
37
    COPY_WSTR("executable", config->executable);
4124
37
    COPY_WSTR("_base_executable", config->base_executable);
4125
37
    COPY_WSTR("prefix", config->prefix);
4126
37
    COPY_WSTR("base_prefix", config->base_prefix);
4127
37
    COPY_WSTR("exec_prefix", config->exec_prefix);
4128
37
    COPY_WSTR("base_exec_prefix", config->base_exec_prefix);
4129
37
    COPY_WSTR("platlibdir", config->platlibdir);
4130
4131
37
    if (config->pycache_prefix != NULL) {
4132
0
        SET_SYS_FROM_WSTR("pycache_prefix", config->pycache_prefix);
4133
37
    } else {
4134
37
        if (PyDict_SetItemString(sysdict, "pycache_prefix", Py_None) < 0) {
4135
0
            return -1;
4136
0
        }
4137
37
    }
4138
4139
37
    COPY_LIST("argv", config->argv);
4140
37
    COPY_LIST("orig_argv", config->orig_argv);
4141
37
    COPY_LIST("warnoptions", config->warnoptions);
4142
4143
37
    SET_SYS("_xoptions", _PyConfig_CreateXOptionsDict(config));
4144
4145
37
    const wchar_t *stdlibdir = _Py_GetStdlibDir();
4146
37
    if (stdlibdir != NULL) {
4147
37
        SET_SYS_FROM_WSTR("_stdlib_dir", stdlibdir);
4148
37
    }
4149
0
    else {
4150
0
        if (PyDict_SetItemString(sysdict, "_stdlib_dir", Py_None) < 0) {
4151
0
            return -1;
4152
0
        }
4153
0
    }
4154
4155
37
#undef SET_SYS_FROM_WSTR
4156
37
#undef COPY_LIST
4157
37
#undef COPY_WSTR
4158
4159
    // sys.flags
4160
37
    PyObject *flags = PySys_GetAttrString("flags");
4161
37
    if (flags == NULL) {
4162
0
        return -1;
4163
0
    }
4164
37
    if (set_flags_from_config(interp, flags) < 0) {
4165
0
        Py_DECREF(flags);
4166
0
        return -1;
4167
0
    }
4168
37
    Py_DECREF(flags);
4169
4170
37
    SET_SYS("dont_write_bytecode", PyBool_FromLong(!config->write_bytecode));
4171
4172
37
    if (_PyErr_Occurred(tstate)) {
4173
0
        goto err_occurred;
4174
0
    }
4175
4176
37
    return 0;
4177
4178
0
err_occurred:
4179
0
    return -1;
4180
37
}
4181
4182
#undef SET_SYS
4183
#undef SET_SYS_FROM_STRING
4184
4185
4186
/* Set up a preliminary stderr printer until we have enough
4187
   infrastructure for the io module in place.
4188
4189
   Use UTF-8/backslashreplace and ignore EAGAIN errors. */
4190
static PyStatus
4191
_PySys_SetPreliminaryStderr(PyObject *sysdict)
4192
37
{
4193
37
    PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr));
4194
37
    if (pstderr == NULL) {
4195
0
        goto error;
4196
0
    }
4197
37
    if (PyDict_SetItem(sysdict, &_Py_ID(stderr), pstderr) < 0) {
4198
0
        goto error;
4199
0
    }
4200
37
    if (PyDict_SetItemString(sysdict, "__stderr__", pstderr) < 0) {
4201
0
        goto error;
4202
0
    }
4203
37
    Py_DECREF(pstderr);
4204
37
    return _PyStatus_OK();
4205
4206
0
error:
4207
0
    Py_XDECREF(pstderr);
4208
0
    return _PyStatus_ERR("can't set preliminary stderr");
4209
37
}
4210
4211
PyObject *_Py_CreateMonitoringObject(void);
4212
4213
/*[clinic input]
4214
module _jit
4215
[clinic start generated code]*/
4216
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=10952f74d7bbd972]*/
4217
4218
PyDoc_STRVAR(_jit_doc, "Utilities for observing just-in-time compilation.");
4219
4220
/*[clinic input]
4221
@permit_long_summary
4222
_jit.is_available -> bool
4223
Return True if the current Python executable supports JIT compilation, and False otherwise.
4224
[clinic start generated code]*/
4225
4226
static int
4227
_jit_is_available_impl(PyObject *module)
4228
/*[clinic end generated code: output=6849a9cd2ff4aac9 input=d009d751ae64c9ef]*/
4229
0
{
4230
0
    (void)module;
4231
#ifdef _Py_TIER2
4232
    return true;
4233
#else
4234
0
    return false;
4235
0
#endif
4236
0
}
4237
4238
/*[clinic input]
4239
@permit_long_summary
4240
_jit.is_enabled -> bool
4241
Return True if JIT compilation is enabled for the current Python process (implies sys._jit.is_available()), and False otherwise.
4242
[clinic start generated code]*/
4243
4244
static int
4245
_jit_is_enabled_impl(PyObject *module)
4246
/*[clinic end generated code: output=55865f8de993fe42 input=0524151e857f4f3a]*/
4247
0
{
4248
0
    (void)module;
4249
0
    return _PyInterpreterState_GET()->jit;
4250
0
}
4251
4252
/*[clinic input]
4253
@permit_long_summary
4254
_jit.is_active -> bool
4255
Return True if the topmost Python frame is currently executing JIT code (implies sys._jit.is_enabled()), and False otherwise.
4256
[clinic start generated code]*/
4257
4258
static int
4259
_jit_is_active_impl(PyObject *module)
4260
/*[clinic end generated code: output=7facca06b10064d4 input=081ee32563dc2086]*/
4261
0
{
4262
0
    (void)module;
4263
0
    return _PyThreadState_GET()->current_executor != NULL;
4264
0
}
4265
4266
static PyMethodDef _jit_methods[] = {
4267
    _JIT_IS_AVAILABLE_METHODDEF
4268
    _JIT_IS_ENABLED_METHODDEF
4269
    _JIT_IS_ACTIVE_METHODDEF
4270
    {NULL}
4271
};
4272
4273
static struct PyModuleDef _jit_module = {
4274
    PyModuleDef_HEAD_INIT,
4275
    .m_name = "sys._jit",
4276
    .m_doc = _jit_doc,
4277
    .m_size = -1,
4278
    .m_methods = _jit_methods,
4279
};
4280
4281
/* Create sys module without all attributes.
4282
   _PySys_UpdateConfig() should be called later to add remaining attributes. */
4283
PyStatus
4284
_PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
4285
37
{
4286
37
    assert(!_PyErr_Occurred(tstate));
4287
4288
37
    PyInterpreterState *interp = tstate->interp;
4289
4290
37
    PyObject *modules = _PyImport_InitModules(interp);
4291
37
    if (modules == NULL) {
4292
0
        goto error;
4293
0
    }
4294
4295
37
    PyObject *sysmod = _PyModule_CreateInitialized(&sysmodule, PYTHON_API_VERSION);
4296
37
    if (sysmod == NULL) {
4297
0
        return _PyStatus_ERR("failed to create a module object");
4298
0
    }
4299
#ifdef Py_GIL_DISABLED
4300
    PyUnstable_Module_SetGIL(sysmod, Py_MOD_GIL_NOT_USED);
4301
#endif
4302
4303
37
    PyObject *sysdict = PyModule_GetDict(sysmod);
4304
37
    if (sysdict == NULL) {
4305
0
        goto error;
4306
0
    }
4307
37
    interp->sysdict = Py_NewRef(sysdict);
4308
4309
37
    interp->sysdict_copy = PyDict_Copy(sysdict);
4310
37
    if (interp->sysdict_copy == NULL) {
4311
0
        goto error;
4312
0
    }
4313
4314
37
    if (PyDict_SetItemString(sysdict, "modules", modules) < 0) {
4315
0
        goto error;
4316
0
    }
4317
4318
37
    PyObject *lazy_modules = _PyImport_InitLazyModules(interp); // borrowed reference
4319
37
    if (lazy_modules == NULL) {
4320
0
        goto error;
4321
0
    }
4322
4323
37
    if (PyDict_SetItemString(sysdict, "lazy_modules", lazy_modules) < 0) {
4324
0
        goto error;
4325
0
    }
4326
4327
37
    PyStatus status = _PySys_SetPreliminaryStderr(sysdict);
4328
37
    if (_PyStatus_EXCEPTION(status)) {
4329
0
        return status;
4330
0
    }
4331
4332
37
    status = _PySys_InitCore(tstate, sysdict);
4333
37
    if (_PyStatus_EXCEPTION(status)) {
4334
0
        return status;
4335
0
    }
4336
4337
37
    if (_PyImport_FixupBuiltin(tstate, sysmod, "sys", modules) < 0) {
4338
0
        goto error;
4339
0
    }
4340
4341
37
    PyObject *monitoring = _Py_CreateMonitoringObject();
4342
37
    if (monitoring == NULL) {
4343
0
        goto error;
4344
0
    }
4345
37
    int err = PyDict_SetItemString(sysdict, "monitoring", monitoring);
4346
37
    Py_DECREF(monitoring);
4347
37
    if (err < 0) {
4348
0
        goto error;
4349
0
    }
4350
4351
37
    PyObject *_jit = _PyModule_CreateInitialized(&_jit_module, PYTHON_API_VERSION);
4352
37
    if (_jit == NULL) {
4353
0
        goto error;
4354
0
    }
4355
37
    err = PyDict_SetItemString(sysdict, "_jit", _jit);
4356
37
    Py_DECREF(_jit);
4357
37
    if (err) {
4358
0
        goto error;
4359
0
    }
4360
4361
37
    assert(!_PyErr_Occurred(tstate));
4362
4363
37
    *sysmod_p = sysmod;
4364
37
    return _PyStatus_OK();
4365
4366
0
error:
4367
0
    return _PyStatus_ERR("can't initialize sys module");
4368
37
}
4369
4370
4371
void
4372
_PySys_FiniTypes(PyInterpreterState *interp)
4373
0
{
4374
0
    _PyStructSequence_FiniBuiltin(interp, &VersionInfoType);
4375
0
    _PyStructSequence_FiniBuiltin(interp, &FlagsType);
4376
#if defined(MS_WINDOWS)
4377
    _PyStructSequence_FiniBuiltin(interp, &WindowsVersionType);
4378
#endif
4379
0
    _PyStructSequence_FiniBuiltin(interp, &Hash_InfoType);
4380
0
    _PyStructSequence_FiniBuiltin(interp, &AsyncGenHooksType);
4381
#ifdef __EMSCRIPTEN__
4382
    if (_Py_IsMainInterpreter(interp)) {
4383
        Py_CLEAR(EmscriptenInfoType);
4384
    }
4385
#endif
4386
0
}
4387
4388
4389
static PyObject *
4390
makepathobject(const wchar_t *path, wchar_t delim)
4391
0
{
4392
0
    int i, n;
4393
0
    const wchar_t *p;
4394
0
    PyObject *v, *w;
4395
4396
0
    n = 1;
4397
0
    p = path;
4398
0
    while ((p = wcschr(p, delim)) != NULL) {
4399
0
        n++;
4400
0
        p++;
4401
0
    }
4402
0
    v = PyList_New(n);
4403
0
    if (v == NULL)
4404
0
        return NULL;
4405
0
    for (i = 0; ; i++) {
4406
0
        p = wcschr(path, delim);
4407
0
        if (p == NULL)
4408
0
            p = path + wcslen(path); /* End of string */
4409
0
        w = PyUnicode_FromWideChar(path, (Py_ssize_t)(p - path));
4410
0
        if (w == NULL) {
4411
0
            Py_DECREF(v);
4412
0
            return NULL;
4413
0
        }
4414
0
        PyList_SET_ITEM(v, i, w);
4415
0
        if (*p == '\0')
4416
0
            break;
4417
0
        path = p+1;
4418
0
    }
4419
0
    return v;
4420
0
}
4421
4422
// Removed in Python 3.13 API, but kept for the stable ABI
4423
PyAPI_FUNC(void)
4424
PySys_SetPath(const wchar_t *path)
4425
0
{
4426
0
    PyObject *v;
4427
0
    if ((v = makepathobject(path, DELIM)) == NULL)
4428
0
        Py_FatalError("can't create sys.path");
4429
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
4430
0
    if (sys_set_object(interp, &_Py_ID(path), v) != 0) {
4431
0
        Py_FatalError("can't assign sys.path");
4432
0
    }
4433
0
    Py_DECREF(v);
4434
0
}
4435
4436
static PyObject *
4437
make_sys_argv(int argc, wchar_t * const * argv)
4438
0
{
4439
0
    PyObject *list = PyList_New(argc);
4440
0
    if (list == NULL) {
4441
0
        return NULL;
4442
0
    }
4443
4444
0
    for (Py_ssize_t i = 0; i < argc; i++) {
4445
0
        PyObject *v = PyUnicode_FromWideChar(argv[i], -1);
4446
0
        if (v == NULL) {
4447
0
            Py_DECREF(list);
4448
0
            return NULL;
4449
0
        }
4450
0
        PyList_SET_ITEM(list, i, v);
4451
0
    }
4452
0
    return list;
4453
0
}
4454
4455
void
4456
PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
4457
0
{
4458
0
    wchar_t* empty_argv[1] = {L""};
4459
0
    PyThreadState *tstate = _PyThreadState_GET();
4460
4461
0
    if (argc < 1 || argv == NULL) {
4462
        /* Ensure at least one (empty) argument is seen */
4463
0
        argv = empty_argv;
4464
0
        argc = 1;
4465
0
    }
4466
4467
0
    PyObject *av = make_sys_argv(argc, argv);
4468
0
    if (av == NULL) {
4469
0
        Py_FatalError("no mem for sys.argv");
4470
0
    }
4471
0
    if (sys_set_object_str(tstate->interp, "argv", av) != 0) {
4472
0
        Py_DECREF(av);
4473
0
        Py_FatalError("can't assign sys.argv");
4474
0
    }
4475
0
    Py_DECREF(av);
4476
4477
0
    if (updatepath) {
4478
        /* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path.
4479
           If argv[0] is a symlink, use the real path. */
4480
0
        const PyWideStringList argv_list = {.length = argc, .items = argv};
4481
0
        PyObject *path0 = NULL;
4482
0
        if (_PyPathConfig_ComputeSysPath0(&argv_list, &path0)) {
4483
0
            if (path0 == NULL) {
4484
0
                Py_FatalError("can't compute path0 from argv");
4485
0
            }
4486
4487
0
            PyObject *sys_path;
4488
0
            if (PySys_GetOptionalAttr(&_Py_ID(path), &sys_path) < 0) {
4489
0
                Py_FatalError("can't get sys.path");
4490
0
            }
4491
0
            else if (sys_path != NULL) {
4492
0
                if (PyList_Insert(sys_path, 0, path0) < 0) {
4493
0
                    Py_FatalError("can't prepend path0 to sys.path");
4494
0
                }
4495
0
                Py_DECREF(sys_path);
4496
0
            }
4497
0
            Py_DECREF(path0);
4498
0
        }
4499
0
    }
4500
0
}
4501
4502
void
4503
PySys_SetArgv(int argc, wchar_t **argv)
4504
0
{
4505
0
_Py_COMP_DIAG_PUSH
4506
0
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
4507
0
    PySys_SetArgvEx(argc, argv, Py_IsolatedFlag == 0);
4508
0
_Py_COMP_DIAG_POP
4509
0
}
4510
4511
/* Reimplementation of PyFile_WriteString() no calling indirectly
4512
   PyErr_CheckSignals(): avoid the call to PyObject_Str(). */
4513
4514
static int
4515
sys_pyfile_write_unicode(PyObject *unicode, PyObject *file)
4516
0
{
4517
0
    if (file == NULL)
4518
0
        return -1;
4519
0
    assert(unicode != NULL);
4520
0
    PyObject *result = PyObject_CallMethodOneArg(file, &_Py_ID(write), unicode);
4521
0
    if (result == NULL) {
4522
0
        return -1;
4523
0
    }
4524
0
    Py_DECREF(result);
4525
0
    return 0;
4526
0
}
4527
4528
static int
4529
sys_pyfile_write(const char *text, PyObject *file)
4530
0
{
4531
0
    PyObject *unicode = NULL;
4532
0
    int err;
4533
4534
0
    if (file == NULL)
4535
0
        return -1;
4536
4537
0
    unicode = PyUnicode_FromString(text);
4538
0
    if (unicode == NULL)
4539
0
        return -1;
4540
4541
0
    err = sys_pyfile_write_unicode(unicode, file);
4542
0
    Py_DECREF(unicode);
4543
0
    return err;
4544
0
}
4545
4546
/* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
4547
   Adapted from code submitted by Just van Rossum.
4548
4549
   PySys_WriteStdout(format, ...)
4550
   PySys_WriteStderr(format, ...)
4551
4552
      The first function writes to sys.stdout; the second to sys.stderr.  When
4553
      there is a problem, they write to the real (C level) stdout or stderr;
4554
      no exceptions are raised.
4555
4556
      PyErr_CheckSignals() is not called to avoid the execution of the Python
4557
      signal handlers: they may raise a new exception whereas sys_write()
4558
      ignores all exceptions.
4559
4560
      Both take a printf-style format string as their first argument followed
4561
      by a variable length argument list determined by the format string.
4562
4563
      *** WARNING ***
4564
4565
      The format should limit the total size of the formatted output string to
4566
      1000 bytes.  In particular, this means that no unrestricted "%s" formats
4567
      should occur; these should be limited using "%.<N>s where <N> is a
4568
      decimal number calculated so that <N> plus the maximum size of other
4569
      formatted text does not exceed 1000 bytes.  Also watch out for "%f",
4570
      which can print hundreds of digits for very large numbers.
4571
4572
 */
4573
4574
static void
4575
sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
4576
0
{
4577
0
    PyObject *file;
4578
0
    char buffer[1001];
4579
0
    int written;
4580
0
    PyThreadState *tstate = _PyThreadState_GET();
4581
4582
0
    PyObject *exc = _PyErr_GetRaisedException(tstate);
4583
0
    written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
4584
0
    file = PySys_GetAttr(key);
4585
0
    if (sys_pyfile_write(buffer, file) != 0) {
4586
0
        _PyErr_Clear(tstate);
4587
0
        fputs(buffer, fp);
4588
0
    }
4589
0
    if (written < 0 || (size_t)written >= sizeof(buffer)) {
4590
0
        const char *truncated = "... truncated";
4591
0
        if (sys_pyfile_write(truncated, file) != 0)
4592
0
            fputs(truncated, fp);
4593
0
    }
4594
0
    Py_XDECREF(file);
4595
0
    _PyErr_SetRaisedException(tstate, exc);
4596
0
}
4597
4598
void
4599
PySys_WriteStdout(const char *format, ...)
4600
0
{
4601
0
    va_list va;
4602
4603
0
    va_start(va, format);
4604
0
    sys_write(&_Py_ID(stdout), stdout, format, va);
4605
0
    va_end(va);
4606
0
}
4607
4608
void
4609
PySys_WriteStderr(const char *format, ...)
4610
0
{
4611
0
    va_list va;
4612
4613
0
    va_start(va, format);
4614
0
    sys_write(&_Py_ID(stderr), stderr, format, va);
4615
0
    va_end(va);
4616
0
}
4617
4618
static void
4619
sys_format(PyObject *key, FILE *fp, const char *format, va_list va)
4620
0
{
4621
0
    PyObject *file, *message;
4622
0
    const char *utf8;
4623
0
    PyThreadState *tstate = _PyThreadState_GET();
4624
4625
0
    PyObject *exc = _PyErr_GetRaisedException(tstate);
4626
0
    message = PyUnicode_FromFormatV(format, va);
4627
0
    if (message != NULL) {
4628
0
        file = PySys_GetAttr(key);
4629
0
        if (sys_pyfile_write_unicode(message, file) != 0) {
4630
0
            _PyErr_Clear(tstate);
4631
0
            utf8 = PyUnicode_AsUTF8(message);
4632
0
            if (utf8 != NULL)
4633
0
                fputs(utf8, fp);
4634
0
        }
4635
0
        Py_XDECREF(file);
4636
0
        Py_DECREF(message);
4637
0
    }
4638
0
    _PyErr_SetRaisedException(tstate, exc);
4639
0
}
4640
4641
void
4642
PySys_FormatStdout(const char *format, ...)
4643
0
{
4644
0
    va_list va;
4645
4646
0
    va_start(va, format);
4647
0
    sys_format(&_Py_ID(stdout), stdout, format, va);
4648
0
    va_end(va);
4649
0
}
4650
4651
void
4652
PySys_FormatStderr(const char *format, ...)
4653
0
{
4654
0
    va_list va;
4655
4656
0
    va_start(va, format);
4657
0
    sys_format(&_Py_ID(stderr), stderr, format, va);
4658
0
    va_end(va);
4659
0
}
4660
4661
4662
int
4663
_PySys_SetIntMaxStrDigits(int maxdigits)
4664
0
{
4665
0
    if (maxdigits != 0 && maxdigits < _PY_LONG_MAX_STR_DIGITS_THRESHOLD) {
4666
0
        PyErr_Format(
4667
0
            PyExc_ValueError, "maxdigits must be >= %d or 0 for unlimited",
4668
0
            _PY_LONG_MAX_STR_DIGITS_THRESHOLD);
4669
0
        return -1;
4670
0
    }
4671
4672
    // Set sys.flags.int_max_str_digits
4673
0
    const Py_ssize_t pos = SYS_FLAGS_INT_MAX_STR_DIGITS;
4674
0
    if (_PySys_SetFlagInt(pos, maxdigits) < 0) {
4675
0
        return -1;
4676
0
    }
4677
4678
    // Set PyInterpreterState.long_state.max_str_digits
4679
    // and PyInterpreterState.config.int_max_str_digits.
4680
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
4681
0
    interp->long_state.max_str_digits = maxdigits;
4682
0
    interp->config.int_max_str_digits = maxdigits;
4683
0
    return 0;
4684
0
}