Coverage Report

Created: 2025-08-26 06:26

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