Coverage Report

Created: 2026-09-03 06:36

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