Coverage Report

Created: 2025-11-24 06:11

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