Coverage Report

Created: 2025-07-04 06:49

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