Coverage Report

Created: 2026-02-26 06:53

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