Coverage Report

Created: 2026-06-01 06:14

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