Coverage Report

Created: 2025-12-14 07:06

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
844k
{
232
    /* interp must not be NULL, but test it just in case for extra safety */
233
844k
    assert(interp != NULL);
234
844k
    if (!interp) {
235
0
        return 0;
236
0
    }
237
844k
    return (interp->runtime->audit_hooks.head
238
844k
            || interp->audit_hooks
239
41.4k
            || PyDTrace_AUDIT_ENABLED());
240
844k
}
241
242
243
static int
244
sys_audit_tstate(PyThreadState *ts, const char *event,
245
                 const char *argFormat, va_list vargs)
246
819k
{
247
819k
    assert(event != NULL);
248
819k
    assert(!argFormat || !strchr(argFormat, 'N'));
249
250
819k
    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
819k
    assert(ts == _PyThreadState_GET());
258
259
    /* Early exit when no hooks are registered */
260
819k
    PyInterpreterState *is = ts->interp;
261
819k
    if (!should_audit(is)) {
262
37.8k
        return 0;
263
37.8k
    }
264
265
781k
    PyObject *eventName = NULL;
266
781k
    PyObject *eventArgs = NULL;
267
781k
    PyObject *hooks = NULL;
268
781k
    PyObject *hook = NULL;
269
781k
    int res = -1;
270
271
781k
    int dtrace = PyDTrace_AUDIT_ENABLED();
272
273
274
781k
    PyObject *exc = _PyErr_GetRaisedException(ts);
275
276
    /* Initialize event args now */
277
781k
    if (argFormat && argFormat[0]) {
278
781k
        eventArgs = Py_VaBuildValue(argFormat, vargs);
279
781k
        if (eventArgs && !PyTuple_Check(eventArgs)) {
280
192k
            PyObject *argTuple = PyTuple_Pack(1, eventArgs);
281
192k
            Py_SETREF(eventArgs, argTuple);
282
192k
        }
283
781k
    }
284
0
    else {
285
0
        eventArgs = PyTuple_New(0);
286
0
    }
287
781k
    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
781k
    _Py_AuditHookEntry *e = is->runtime->audit_hooks.head;
296
781k
    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
781k
    if (dtrace) {
304
0
        PyDTrace_AUDIT(event, (void *)eventArgs);
305
0
    }
306
307
    /* Call interpreter hooks */
308
781k
    if (is->audit_hooks) {
309
781k
        eventName = PyUnicode_FromString(event);
310
781k
        if (!eventName) {
311
0
            goto exit;
312
0
        }
313
314
781k
        hooks = PyObject_GetIter(is->audit_hooks);
315
781k
        if (!hooks) {
316
0
            goto exit;
317
0
        }
318
319
        /* Disallow tracing in hooks unless explicitly enabled */
320
781k
        PyThreadState_EnterTracing(ts);
321
1.56M
        while ((hook = PyIter_Next(hooks)) != NULL) {
322
781k
            PyObject *o;
323
781k
            int canTrace = PyObject_GetOptionalAttr(hook, &_Py_ID(__cantrace__), &o);
324
781k
            if (o) {
325
0
                canTrace = PyObject_IsTrue(o);
326
0
                Py_DECREF(o);
327
0
            }
328
781k
            if (canTrace < 0) {
329
0
                break;
330
0
            }
331
781k
            if (canTrace) {
332
0
                PyThreadState_LeaveTracing(ts);
333
0
            }
334
781k
            PyObject* args[2] = {eventName, eventArgs};
335
781k
            o = _PyObject_VectorcallTstate(ts, hook, args, 2, NULL);
336
781k
            if (canTrace) {
337
0
                PyThreadState_EnterTracing(ts);
338
0
            }
339
781k
            if (!o) {
340
0
                break;
341
0
            }
342
781k
            Py_DECREF(o);
343
781k
            Py_CLEAR(hook);
344
781k
        }
345
781k
        PyThreadState_LeaveTracing(ts);
346
781k
        if (_PyErr_Occurred(ts)) {
347
0
            goto exit;
348
0
        }
349
781k
    }
350
351
781k
    res = 0;
352
353
781k
exit:
354
781k
    Py_XDECREF(hook);
355
781k
    Py_XDECREF(hooks);
356
781k
    Py_XDECREF(eventName);
357
781k
    Py_XDECREF(eventArgs);
358
359
781k
    if (!res) {
360
781k
        _PyErr_SetRaisedException(ts, exc);
361
781k
    }
362
0
    else {
363
0
        assert(_PyErr_Occurred(ts));
364
0
        Py_XDECREF(exc);
365
0
    }
366
367
781k
    return res;
368
781k
}
369
370
int
371
_PySys_Audit(PyThreadState *tstate, const char *event,
372
             const char *argFormat, ...)
373
21.7k
{
374
21.7k
    va_list vargs;
375
21.7k
    va_start(vargs, argFormat);
376
21.7k
    int res = sys_audit_tstate(tstate, event, argFormat, vargs);
377
21.7k
    va_end(vargs);
378
21.7k
    return res;
379
21.7k
}
380
381
int
382
PySys_Audit(const char *event, const char *argFormat, ...)
383
797k
{
384
797k
    PyThreadState *tstate = _PyThreadState_GET();
385
797k
    va_list vargs;
386
797k
    va_start(vargs, argFormat);
387
797k
    int res = sys_audit_tstate(tstate, event, argFormat, vargs);
388
797k
    va_end(vargs);
389
797k
    return res;
390
797k
}
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
25.1k
{
568
25.1k
    PyThreadState *tstate = _PyThreadState_GET();
569
25.1k
    _Py_EnsureTstateNotNULL(tstate);
570
571
25.1k
    if (!should_audit(tstate->interp)) {
572
3.56k
        Py_RETURN_NONE;
573
3.56k
    }
574
575
21.5k
    int res = _PySys_Audit(tstate, event, "O", args);
576
21.5k
    if (res < 0) {
577
0
        return NULL;
578
0
    }
579
580
21.5k
    Py_RETURN_NONE;
581
21.5k
}
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
834
{
1007
834
    if (PyUnicode_CheckExact(s)) {
1008
834
        PyInterpreterState *interp = _PyInterpreterState_GET();
1009
834
        Py_INCREF(s);
1010
834
        _PyUnicode_InternMortal(interp, &s);
1011
834
        return s;
1012
834
    }
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
834
}
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
86
{
2605
86
    if (PySys_Audit("sys._getframemodulename", "i", depth) < 0) {
2606
0
        return NULL;
2607
0
    }
2608
86
    _PyInterpreterFrame *f = _PyThreadState_GET()->current_frame;
2609
172
    while (f && (_PyFrame_IsIncomplete(f) || depth-- > 0)) {
2610
86
        f = f->previous;
2611
86
    }
2612
86
    if (f == NULL || PyStackRef_IsNull(f->f_funcobj)) {
2613
0
        Py_RETURN_NONE;
2614
0
    }
2615
86
    PyObject *func = PyStackRef_AsPyObjectBorrow(f->f_funcobj);
2616
86
    PyObject *r = PyFunction_GetModule(func);
2617
86
    if (!r) {
2618
0
        PyErr_Clear();
2619
0
        r = Py_None;
2620
0
    }
2621
86
    return Py_NewRef(r);
2622
86
}
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 result = 0;
2757
0
    while (1) {
2758
0
        size_t bytes_read = fread(buf, 1, sizeof(buf), from);
2759
0
        if (bytes_read == 0) {
2760
0
            if (ferror(from)) {
2761
0
                result = -1;
2762
0
            }
2763
0
            break;
2764
0
        }
2765
2766
0
        size_t bytes_written = fwrite(buf, 1, bytes_read, perf_map_state.perf_map);
2767
0
        if (bytes_written < bytes_read) {
2768
0
            result = -1;
2769
0
            break;
2770
0
        }
2771
2772
0
        if (fflush(perf_map_state.perf_map) != 0) {
2773
0
            result = -1;
2774
0
            break;
2775
0
        }
2776
2777
0
        if (bytes_read < sizeof(buf) && feof(from)) {
2778
0
            break;
2779
0
        }
2780
0
    }
2781
0
    fclose(from);
2782
0
    PyThread_release_lock(perf_map_state.map_lock);
2783
0
    return result;
2784
0
#endif
2785
0
    return 0;
2786
0
}
2787
2788
2789
static PyMethodDef sys_methods[] = {
2790
    /* Might as well keep this in alphabetic order */
2791
    SYS_ADDAUDITHOOK_METHODDEF
2792
    SYS_AUDIT_METHODDEF
2793
    {"breakpointhook", _PyCFunction_CAST(sys_breakpointhook),
2794
     METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc},
2795
    SYS__CLEAR_INTERNAL_CACHES_METHODDEF
2796
    SYS__CLEAR_TYPE_CACHE_METHODDEF
2797
    SYS__CURRENT_FRAMES_METHODDEF
2798
    SYS__CURRENT_EXCEPTIONS_METHODDEF
2799
    SYS_DISPLAYHOOK_METHODDEF
2800
    SYS_EXCEPTION_METHODDEF
2801
    SYS_EXC_INFO_METHODDEF
2802
    SYS_EXCEPTHOOK_METHODDEF
2803
    SYS_EXIT_METHODDEF
2804
    SYS_GETDEFAULTENCODING_METHODDEF
2805
    SYS_GETDLOPENFLAGS_METHODDEF
2806
    SYS_GETALLOCATEDBLOCKS_METHODDEF
2807
    SYS_GETUNICODEINTERNEDSIZE_METHODDEF
2808
    SYS_GETFILESYSTEMENCODING_METHODDEF
2809
    SYS_GETFILESYSTEMENCODEERRORS_METHODDEF
2810
#ifdef Py_TRACE_REFS
2811
    {"getobjects", _Py_GetObjects, METH_VARARGS},
2812
#endif
2813
    SYS_GETTOTALREFCOUNT_METHODDEF
2814
    SYS_GETREFCOUNT_METHODDEF
2815
    SYS_GETRECURSIONLIMIT_METHODDEF
2816
    {"getsizeof", _PyCFunction_CAST(sys_getsizeof),
2817
     METH_VARARGS | METH_KEYWORDS, getsizeof_doc},
2818
    SYS__GETFRAME_METHODDEF
2819
    SYS__GETFRAMEMODULENAME_METHODDEF
2820
    SYS_GETWINDOWSVERSION_METHODDEF
2821
    SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF
2822
    SYS__IS_IMMORTAL_METHODDEF
2823
    SYS_INTERN_METHODDEF
2824
    SYS__IS_INTERNED_METHODDEF
2825
    SYS_IS_FINALIZING_METHODDEF
2826
    SYS_MDEBUG_METHODDEF
2827
    SYS_SETSWITCHINTERVAL_METHODDEF
2828
    SYS_GETSWITCHINTERVAL_METHODDEF
2829
    SYS_SETDLOPENFLAGS_METHODDEF
2830
    SYS_SETPROFILE_METHODDEF
2831
    SYS__SETPROFILEALLTHREADS_METHODDEF
2832
    SYS_GETPROFILE_METHODDEF
2833
    SYS_SETRECURSIONLIMIT_METHODDEF
2834
    SYS_SETTRACE_METHODDEF
2835
    SYS__SETTRACEALLTHREADS_METHODDEF
2836
    SYS_GETTRACE_METHODDEF
2837
    SYS_CALL_TRACING_METHODDEF
2838
    SYS__DEBUGMALLOCSTATS_METHODDEF
2839
    SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF
2840
    SYS_GET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF
2841
    {"set_asyncgen_hooks", _PyCFunction_CAST(sys_set_asyncgen_hooks),
2842
     METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc},
2843
    SYS_GET_ASYNCGEN_HOOKS_METHODDEF
2844
    SYS_GETANDROIDAPILEVEL_METHODDEF
2845
    SYS_ACTIVATE_STACK_TRAMPOLINE_METHODDEF
2846
    SYS_DEACTIVATE_STACK_TRAMPOLINE_METHODDEF
2847
    SYS_IS_STACK_TRAMPOLINE_ACTIVE_METHODDEF
2848
    SYS_IS_REMOTE_DEBUG_ENABLED_METHODDEF
2849
    SYS_REMOTE_EXEC_METHODDEF
2850
    SYS_UNRAISABLEHOOK_METHODDEF
2851
    SYS_GET_INT_MAX_STR_DIGITS_METHODDEF
2852
    SYS_SET_INT_MAX_STR_DIGITS_METHODDEF
2853
    SYS__BASEREPL_METHODDEF
2854
#ifdef Py_STATS
2855
    SYS__STATS_ON_METHODDEF
2856
    SYS__STATS_OFF_METHODDEF
2857
    SYS__STATS_CLEAR_METHODDEF
2858
    SYS__STATS_DUMP_METHODDEF
2859
#endif
2860
    SYS__GET_CPU_COUNT_CONFIG_METHODDEF
2861
    SYS__IS_GIL_ENABLED_METHODDEF
2862
    SYS__DUMP_TRACELETS_METHODDEF
2863
    {NULL, NULL}  // sentinel
2864
};
2865
2866
2867
static PyObject *
2868
list_builtin_module_names(void)
2869
28
{
2870
28
    PyObject *list = _PyImport_GetBuiltinModuleNames();
2871
28
    if (list == NULL) {
2872
0
        return NULL;
2873
0
    }
2874
28
    if (PyList_Sort(list) != 0) {
2875
0
        goto error;
2876
0
    }
2877
28
    PyObject *tuple = PyList_AsTuple(list);
2878
28
    Py_DECREF(list);
2879
28
    return tuple;
2880
2881
0
error:
2882
0
    Py_DECREF(list);
2883
0
    return NULL;
2884
28
}
2885
2886
2887
static PyObject *
2888
list_stdlib_module_names(void)
2889
28
{
2890
28
    Py_ssize_t len = Py_ARRAY_LENGTH(_Py_stdlib_module_names);
2891
28
    PyObject *names = PyTuple_New(len);
2892
28
    if (names == NULL) {
2893
0
        return NULL;
2894
0
    }
2895
2896
8.31k
    for (Py_ssize_t i = 0; i < len; i++) {
2897
8.28k
        PyObject *name = PyUnicode_FromString(_Py_stdlib_module_names[i]);
2898
8.28k
        if (name == NULL) {
2899
0
            Py_DECREF(names);
2900
0
            return NULL;
2901
0
        }
2902
8.28k
        PyTuple_SET_ITEM(names, i, name);
2903
8.28k
    }
2904
2905
28
    PyObject *set = PyObject_CallFunction((PyObject *)&PyFrozenSet_Type,
2906
28
                                          "(O)", names);
2907
28
    Py_DECREF(names);
2908
28
    return set;
2909
28
}
2910
2911
2912
/* Pre-initialization support for sys.warnoptions and sys._xoptions
2913
 *
2914
 * Modern internal code paths:
2915
 *   These APIs get called after _Py_InitializeCore and get to use the
2916
 *   regular CPython list, dict, and unicode APIs.
2917
 *
2918
 * Legacy embedding code paths:
2919
 *   The multi-phase initialization API isn't public yet, so embedding
2920
 *   apps still need to be able configure sys.warnoptions and sys._xoptions
2921
 *   before they call Py_Initialize. To support this, we stash copies of
2922
 *   the supplied wchar * sequences in linked lists, and then migrate the
2923
 *   contents of those lists to the sys module in _PyInitializeCore.
2924
 *
2925
 */
2926
2927
struct _preinit_entry {
2928
    wchar_t *value;
2929
    struct _preinit_entry *next;
2930
};
2931
2932
typedef struct _preinit_entry *_Py_PreInitEntry;
2933
2934
static _Py_PreInitEntry _preinit_warnoptions = NULL;
2935
static _Py_PreInitEntry _preinit_xoptions = NULL;
2936
2937
static _Py_PreInitEntry
2938
_alloc_preinit_entry(const wchar_t *value)
2939
0
{
2940
    /* To get this to work, we have to initialize the runtime implicitly */
2941
0
    _PyRuntime_Initialize();
2942
2943
    /* Use the default allocator, so we can ensure that it also gets used to
2944
     * destroy the linked list in _clear_preinit_entries.
2945
     */
2946
0
    _Py_PreInitEntry node = _PyMem_DefaultRawCalloc(1, sizeof(*node));
2947
0
    if (node != NULL) {
2948
0
        node->value = _PyMem_DefaultRawWcsdup(value);
2949
0
        if (node->value == NULL) {
2950
0
            _PyMem_DefaultRawFree(node);
2951
0
            node = NULL;
2952
0
        };
2953
0
    };
2954
0
    return node;
2955
0
}
2956
2957
static int
2958
_append_preinit_entry(_Py_PreInitEntry *optionlist, const wchar_t *value)
2959
0
{
2960
0
    _Py_PreInitEntry new_entry = _alloc_preinit_entry(value);
2961
0
    if (new_entry == NULL) {
2962
0
        return -1;
2963
0
    }
2964
    /* We maintain the linked list in this order so it's easy to play back
2965
     * the add commands in the same order later on in _Py_InitializeCore
2966
     */
2967
0
    _Py_PreInitEntry last_entry = *optionlist;
2968
0
    if (last_entry == NULL) {
2969
0
        *optionlist = new_entry;
2970
0
    } else {
2971
0
        while (last_entry->next != NULL) {
2972
0
            last_entry = last_entry->next;
2973
0
        }
2974
0
        last_entry->next = new_entry;
2975
0
    }
2976
0
    return 0;
2977
0
}
2978
2979
static void
2980
_clear_preinit_entries(_Py_PreInitEntry *optionlist)
2981
56
{
2982
56
    _Py_PreInitEntry current = *optionlist;
2983
56
    *optionlist = NULL;
2984
    /* Deallocate the nodes and their contents using the default allocator */
2985
56
    while (current != NULL) {
2986
0
        _Py_PreInitEntry next = current->next;
2987
0
        _PyMem_DefaultRawFree(current->value);
2988
0
        _PyMem_DefaultRawFree(current);
2989
0
        current = next;
2990
0
    }
2991
56
}
2992
2993
2994
PyStatus
2995
_PySys_ReadPreinitWarnOptions(PyWideStringList *options)
2996
28
{
2997
28
    PyStatus status;
2998
28
    _Py_PreInitEntry entry;
2999
3000
28
    for (entry = _preinit_warnoptions; entry != NULL; entry = entry->next) {
3001
0
        status = PyWideStringList_Append(options, entry->value);
3002
0
        if (_PyStatus_EXCEPTION(status)) {
3003
0
            return status;
3004
0
        }
3005
0
    }
3006
3007
28
    _clear_preinit_entries(&_preinit_warnoptions);
3008
28
    return _PyStatus_OK();
3009
28
}
3010
3011
3012
PyStatus
3013
_PySys_ReadPreinitXOptions(PyConfig *config)
3014
28
{
3015
28
    PyStatus status;
3016
28
    _Py_PreInitEntry entry;
3017
3018
28
    for (entry = _preinit_xoptions; entry != NULL; entry = entry->next) {
3019
0
        status = PyWideStringList_Append(&config->xoptions, entry->value);
3020
0
        if (_PyStatus_EXCEPTION(status)) {
3021
0
            return status;
3022
0
        }
3023
0
    }
3024
3025
28
    _clear_preinit_entries(&_preinit_xoptions);
3026
28
    return _PyStatus_OK();
3027
28
}
3028
3029
3030
static PyObject *
3031
get_warnoptions(PyThreadState *tstate)
3032
0
{
3033
0
    PyObject *warnoptions;
3034
0
    if (PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
3035
0
        return NULL;
3036
0
    }
3037
0
    if (warnoptions == NULL || !PyList_Check(warnoptions)) {
3038
        /* PEP432 TODO: we can reach this if warnoptions is NULL in the main
3039
        *  interpreter config. When that happens, we need to properly set
3040
         * the `warnoptions` reference in the main interpreter config as well.
3041
         *
3042
         * For Python 3.7, we shouldn't be able to get here due to the
3043
         * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit
3044
         * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig
3045
         * call optional for embedding applications, thus making this
3046
         * reachable again.
3047
         */
3048
0
        Py_XDECREF(warnoptions);
3049
0
        warnoptions = PyList_New(0);
3050
0
        if (warnoptions == NULL) {
3051
0
            return NULL;
3052
0
        }
3053
0
        if (sys_set_object(tstate->interp, &_Py_ID(warnoptions), warnoptions)) {
3054
0
            Py_DECREF(warnoptions);
3055
0
            return NULL;
3056
0
        }
3057
0
    }
3058
0
    return warnoptions;
3059
0
}
3060
3061
PyAPI_FUNC(void)
3062
PySys_ResetWarnOptions(void)
3063
0
{
3064
0
    PyThreadState *tstate = _PyThreadState_GET();
3065
0
    if (tstate == NULL) {
3066
0
        _clear_preinit_entries(&_preinit_warnoptions);
3067
0
        return;
3068
0
    }
3069
3070
0
    PyObject *warnoptions;
3071
0
    if (PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
3072
0
        PyErr_Clear();
3073
0
        return;
3074
0
    }
3075
0
    if (warnoptions != NULL && PyList_Check(warnoptions)) {
3076
0
        PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
3077
0
    }
3078
0
    Py_XDECREF(warnoptions);
3079
0
}
3080
3081
static int
3082
_PySys_AddWarnOptionWithError(PyThreadState *tstate, PyObject *option)
3083
0
{
3084
0
    assert(tstate != NULL);
3085
0
    PyObject *warnoptions = get_warnoptions(tstate);
3086
0
    if (warnoptions == NULL) {
3087
0
        return -1;
3088
0
    }
3089
0
    if (PyList_Append(warnoptions, option)) {
3090
0
        Py_DECREF(warnoptions);
3091
0
        return -1;
3092
0
    }
3093
0
    Py_DECREF(warnoptions);
3094
0
    return 0;
3095
0
}
3096
3097
// Removed in Python 3.13 API, but kept for the stable ABI
3098
PyAPI_FUNC(void)
3099
PySys_AddWarnOptionUnicode(PyObject *option)
3100
0
{
3101
0
    PyThreadState *tstate = _PyThreadState_GET();
3102
0
    _Py_EnsureTstateNotNULL(tstate);
3103
0
    assert(!_PyErr_Occurred(tstate));
3104
0
    if (_PySys_AddWarnOptionWithError(tstate, option) < 0) {
3105
        /* No return value, therefore clear error state if possible */
3106
0
        _PyErr_Clear(tstate);
3107
0
    }
3108
0
}
3109
3110
// Removed in Python 3.13 API, but kept for the stable ABI
3111
PyAPI_FUNC(void)
3112
PySys_AddWarnOption(const wchar_t *s)
3113
0
{
3114
0
    PyThreadState *tstate = _PyThreadState_GET();
3115
0
    if (tstate == NULL) {
3116
0
        _append_preinit_entry(&_preinit_warnoptions, s);
3117
0
        return;
3118
0
    }
3119
0
    PyObject *unicode;
3120
0
    unicode = PyUnicode_FromWideChar(s, -1);
3121
0
    if (unicode == NULL)
3122
0
        return;
3123
0
_Py_COMP_DIAG_PUSH
3124
0
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
3125
0
    PySys_AddWarnOptionUnicode(unicode);
3126
0
_Py_COMP_DIAG_POP
3127
0
    Py_DECREF(unicode);
3128
0
}
3129
3130
// Removed in Python 3.13 API, but kept for the stable ABI
3131
PyAPI_FUNC(int)
3132
PySys_HasWarnOptions(void)
3133
0
{
3134
0
    PyObject *warnoptions;
3135
0
    if (PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
3136
0
        PyErr_Clear();
3137
0
        return 0;
3138
0
    }
3139
0
    int r = (warnoptions != NULL && PyList_Check(warnoptions) &&
3140
0
             PyList_GET_SIZE(warnoptions) > 0);
3141
0
    Py_XDECREF(warnoptions);
3142
0
    return r;
3143
0
}
3144
3145
static PyObject *
3146
get_xoptions(PyThreadState *tstate)
3147
0
{
3148
0
    PyObject *xoptions;
3149
0
    if (PySys_GetOptionalAttr(&_Py_ID(_xoptions), &xoptions) < 0) {
3150
0
        return NULL;
3151
0
    }
3152
0
    if (xoptions == NULL || !PyDict_Check(xoptions)) {
3153
        /* PEP432 TODO: we can reach this if xoptions is NULL in the main
3154
        *  interpreter config. When that happens, we need to properly set
3155
         * the `xoptions` reference in the main interpreter config as well.
3156
         *
3157
         * For Python 3.7, we shouldn't be able to get here due to the
3158
         * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit
3159
         * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig
3160
         * call optional for embedding applications, thus making this
3161
         * reachable again.
3162
         */
3163
0
        Py_XDECREF(xoptions);
3164
0
        xoptions = PyDict_New();
3165
0
        if (xoptions == NULL) {
3166
0
            return NULL;
3167
0
        }
3168
0
        if (sys_set_object(tstate->interp, &_Py_ID(_xoptions), xoptions)) {
3169
0
            Py_DECREF(xoptions);
3170
0
            return NULL;
3171
0
        }
3172
0
    }
3173
0
    return xoptions;
3174
0
}
3175
3176
static int
3177
_PySys_AddXOptionWithError(const wchar_t *s)
3178
0
{
3179
0
    PyObject *name = NULL, *value = NULL;
3180
3181
0
    PyThreadState *tstate = _PyThreadState_GET();
3182
0
    PyObject *opts = get_xoptions(tstate);
3183
0
    if (opts == NULL) {
3184
0
        goto error;
3185
0
    }
3186
3187
0
    const wchar_t *name_end = wcschr(s, L'=');
3188
0
    if (!name_end) {
3189
0
        name = PyUnicode_FromWideChar(s, -1);
3190
0
        if (name == NULL) {
3191
0
            goto error;
3192
0
        }
3193
0
        value = Py_NewRef(Py_True);
3194
0
    }
3195
0
    else {
3196
0
        name = PyUnicode_FromWideChar(s, name_end - s);
3197
0
        if (name == NULL) {
3198
0
            goto error;
3199
0
        }
3200
0
        value = PyUnicode_FromWideChar(name_end + 1, -1);
3201
0
        if (value == NULL) {
3202
0
            goto error;
3203
0
        }
3204
0
    }
3205
0
    if (PyDict_SetItem(opts, name, value) < 0) {
3206
0
        goto error;
3207
0
    }
3208
0
    Py_DECREF(name);
3209
0
    Py_DECREF(value);
3210
0
    Py_DECREF(opts);
3211
0
    return 0;
3212
3213
0
error:
3214
0
    Py_XDECREF(name);
3215
0
    Py_XDECREF(value);
3216
0
    Py_XDECREF(opts);
3217
0
    return -1;
3218
0
}
3219
3220
// Removed in Python 3.13 API, but kept for the stable ABI
3221
PyAPI_FUNC(void)
3222
PySys_AddXOption(const wchar_t *s)
3223
0
{
3224
0
    PyThreadState *tstate = _PyThreadState_GET();
3225
0
    if (tstate == NULL) {
3226
0
        _append_preinit_entry(&_preinit_xoptions, s);
3227
0
        return;
3228
0
    }
3229
0
    if (_PySys_AddXOptionWithError(s) < 0) {
3230
        /* No return value, therefore clear error state if possible */
3231
0
        _PyErr_Clear(tstate);
3232
0
    }
3233
0
}
3234
3235
PyObject *
3236
PySys_GetXOptions(void)
3237
0
{
3238
0
    PyThreadState *tstate = _PyThreadState_GET();
3239
0
    PyObject *opts = get_xoptions(tstate);
3240
0
    Py_XDECREF(opts);
3241
0
    return opts;
3242
0
}
3243
3244
/* XXX This doc string is too long to be a single string literal in VC++ 5.0.
3245
   Two literals concatenated works just fine.  If you have a K&R compiler
3246
   or other abomination that however *does* understand longer strings,
3247
   get rid of the !!! comment in the middle and the quotes that surround it. */
3248
PyDoc_VAR(sys_doc) =
3249
PyDoc_STR(
3250
"This module provides access to some objects used or maintained by the\n\
3251
interpreter and to functions that interact strongly with the interpreter.\n\
3252
\n\
3253
Dynamic objects:\n\
3254
\n\
3255
argv -- command line arguments; argv[0] is the script pathname if known\n\
3256
path -- module search path; path[0] is the script directory, else ''\n\
3257
modules -- dictionary of loaded modules\n\
3258
\n\
3259
displayhook -- called to show results in an interactive session\n\
3260
excepthook -- called to handle any uncaught exception other than SystemExit\n\
3261
  To customize printing in an interactive session or to install a custom\n\
3262
  top-level exception handler, assign other functions to replace these.\n\
3263
\n\
3264
stdin -- standard input file object; used by input()\n\
3265
stdout -- standard output file object; used by print()\n\
3266
stderr -- standard error object; used for error messages\n\
3267
  By assigning other file objects (or objects that behave like files)\n\
3268
  to these, it is possible to redirect all of the interpreter's I/O.\n\
3269
\n\
3270
last_exc - the last uncaught exception\n\
3271
  Only available in an interactive session after a\n\
3272
  traceback has been printed.\n\
3273
last_type -- type of last uncaught exception\n\
3274
last_value -- value of last uncaught exception\n\
3275
last_traceback -- traceback of last uncaught exception\n\
3276
  These three are the (deprecated) legacy representation of last_exc.\n\
3277
"
3278
)
3279
/* concatenating string here */
3280
PyDoc_STR(
3281
"\n\
3282
Static objects:\n\
3283
\n\
3284
abi_info -- Python ABI information.\n\
3285
builtin_module_names -- tuple of module names built into this interpreter\n\
3286
copyright -- copyright notice pertaining to this interpreter\n\
3287
exec_prefix -- prefix used to find the machine-specific Python library\n\
3288
executable -- absolute path of the executable binary of the Python interpreter\n\
3289
float_info -- a named tuple with information about the float implementation.\n\
3290
float_repr_style -- string indicating the style of repr() output for floats\n\
3291
hash_info -- a named tuple with information about the hash algorithm.\n\
3292
hexversion -- version information encoded as a single integer\n\
3293
implementation -- Python implementation information.\n\
3294
int_info -- a named tuple with information about the int implementation.\n\
3295
maxsize -- the largest supported length of containers.\n\
3296
maxunicode -- the value of the largest Unicode code point\n\
3297
platform -- platform identifier\n\
3298
prefix -- prefix used to find the Python library\n\
3299
thread_info -- a named tuple with information about the thread implementation.\n\
3300
version -- the version of this interpreter as a string\n\
3301
version_info -- version information as a named tuple\n\
3302
"
3303
)
3304
#ifdef MS_COREDLL
3305
/* concatenating string here */
3306
PyDoc_STR(
3307
"dllhandle -- [Windows only] integer handle of the Python DLL\n\
3308
winver -- [Windows only] version number of the Python DLL\n\
3309
"
3310
)
3311
#endif /* MS_COREDLL */
3312
#ifdef MS_WINDOWS
3313
/* concatenating string here */
3314
PyDoc_STR(
3315
"_enablelegacywindowsfsencoding -- [Windows only]\n\
3316
"
3317
)
3318
#endif
3319
PyDoc_STR(
3320
"__stdin__ -- the original stdin; don't touch!\n\
3321
__stdout__ -- the original stdout; don't touch!\n\
3322
__stderr__ -- the original stderr; don't touch!\n\
3323
__displayhook__ -- the original displayhook; don't touch!\n\
3324
__excepthook__ -- the original excepthook; don't touch!\n\
3325
\n\
3326
Functions:\n\
3327
\n\
3328
displayhook() -- print an object to the screen, and save it in builtins._\n\
3329
excepthook() -- print an exception and its traceback to sys.stderr\n\
3330
exception() -- return the current thread's active exception\n\
3331
exc_info() -- return information about the current thread's active exception\n\
3332
exit() -- exit the interpreter by raising SystemExit\n\
3333
getdlopenflags() -- returns flags to be used for dlopen() calls\n\
3334
getprofile() -- get the global profiling function\n\
3335
getrefcount() -- return the reference count for an object (plus one :-)\n\
3336
getrecursionlimit() -- return the max recursion depth for the interpreter\n\
3337
getsizeof() -- return the size of an object in bytes\n\
3338
gettrace() -- get the global debug tracing function\n\
3339
setdlopenflags() -- set the flags to be used for dlopen() calls\n\
3340
setprofile() -- set the global profiling function\n\
3341
setrecursionlimit() -- set the max recursion depth for the interpreter\n\
3342
settrace() -- set the global debug tracing function\n\
3343
"
3344
)
3345
/* end of sys_doc */ ;
3346
3347
3348
PyDoc_STRVAR(flags__doc__,
3349
"sys.flags\n\
3350
\n\
3351
Flags provided through command line arguments or environment vars.");
3352
3353
static PyTypeObject FlagsType;
3354
3355
static PyStructSequence_Field flags_fields[] = {
3356
    {"debug",                   "-d"},
3357
    {"inspect",                 "-i"},
3358
    {"interactive",             "-i"},
3359
    {"optimize",                "-O or -OO"},
3360
    {"dont_write_bytecode",     "-B"},
3361
    {"no_user_site",            "-s"},
3362
    {"no_site",                 "-S"},
3363
    {"ignore_environment",      "-E"},
3364
    {"verbose",                 "-v"},
3365
    {"bytes_warning",           "-b"},
3366
    {"quiet",                   "-q"},
3367
    {"hash_randomization",      "-R"},
3368
    {"isolated",                "-I"},
3369
    {"dev_mode",                "-X dev"},
3370
    {"utf8_mode",               "-X utf8"},
3371
    {"warn_default_encoding",   "-X warn_default_encoding"},
3372
    {"safe_path", "-P"},
3373
    {"int_max_str_digits",      "-X int_max_str_digits"},
3374
    {"gil",                     "-X gil"},
3375
    {"thread_inherit_context",  "-X thread_inherit_context"},
3376
    {"context_aware_warnings",    "-X context_aware_warnings"},
3377
    {0}
3378
};
3379
3380
0
#define SYS_FLAGS_INT_MAX_STR_DIGITS 17
3381
3382
static PyStructSequence_Desc flags_desc = {
3383
    "sys.flags",        /* name */
3384
    flags__doc__,       /* doc */
3385
    flags_fields,       /* fields */
3386
    18
3387
};
3388
3389
static void
3390
sys_set_flag(PyObject *flags, Py_ssize_t pos, PyObject *value)
3391
1.17k
{
3392
1.17k
    assert(pos >= 0 && pos < (Py_ssize_t)(Py_ARRAY_LENGTH(flags_fields) - 1));
3393
3394
1.17k
    PyObject *old_value = PyStructSequence_GET_ITEM(flags, pos);
3395
1.17k
    PyStructSequence_SET_ITEM(flags, pos, Py_NewRef(value));
3396
1.17k
    Py_XDECREF(old_value);
3397
1.17k
}
3398
3399
3400
int
3401
_PySys_SetFlagObj(Py_ssize_t pos, PyObject *value)
3402
0
{
3403
0
    PyObject *flags = PySys_GetAttrString("flags");
3404
0
    if (flags == NULL) {
3405
0
        return -1;
3406
0
    }
3407
3408
0
    sys_set_flag(flags, pos, value);
3409
0
    Py_DECREF(flags);
3410
0
    return 0;
3411
0
}
3412
3413
3414
static int
3415
_PySys_SetFlagInt(Py_ssize_t pos, int value)
3416
0
{
3417
0
    PyObject *obj = PyLong_FromLong(value);
3418
0
    if (obj == NULL) {
3419
0
        return -1;
3420
0
    }
3421
3422
0
    int res = _PySys_SetFlagObj(pos, obj);
3423
0
    Py_DECREF(obj);
3424
0
    return res;
3425
0
}
3426
3427
3428
static int
3429
set_flags_from_config(PyInterpreterState *interp, PyObject *flags)
3430
56
{
3431
56
    const PyPreConfig *preconfig = &interp->runtime->preconfig;
3432
56
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);
3433
3434
    // _PySys_UpdateConfig() modifies sys.flags in-place:
3435
    // Py_XDECREF() is needed in this case.
3436
56
    Py_ssize_t pos = 0;
3437
56
#define SetFlagObj(expr) \
3438
1.17k
    do { \
3439
1.17k
        PyObject *value = (expr); \
3440
1.17k
        if (value == NULL) { \
3441
0
            return -1; \
3442
0
        } \
3443
1.17k
        sys_set_flag(flags, pos, value); \
3444
1.17k
        Py_DECREF(value); \
3445
1.17k
        pos++; \
3446
1.17k
    } while (0)
3447
1.00k
#define SetFlag(expr) SetFlagObj(PyLong_FromLong(expr))
3448
3449
56
    SetFlag(config->parser_debug);
3450
56
    SetFlag(config->inspect);
3451
56
    SetFlag(config->interactive);
3452
56
    SetFlag(config->optimization_level);
3453
56
    SetFlag(!config->write_bytecode);
3454
56
    SetFlag(!config->user_site_directory);
3455
56
    SetFlag(!config->site_import);
3456
56
    SetFlag(!config->use_environment);
3457
56
    SetFlag(config->verbose);
3458
56
    SetFlag(config->bytes_warning);
3459
56
    SetFlag(config->quiet);
3460
56
    SetFlag(config->use_hash_seed == 0 || config->hash_seed != 0);
3461
56
    SetFlag(config->isolated);
3462
56
    SetFlagObj(PyBool_FromLong(config->dev_mode));
3463
56
    SetFlag(preconfig->utf8_mode);
3464
56
    SetFlag(config->warn_default_encoding);
3465
56
    SetFlagObj(PyBool_FromLong(config->safe_path));
3466
56
    SetFlag(config->int_max_str_digits);
3467
#ifdef Py_GIL_DISABLED
3468
    if (config->enable_gil == _PyConfig_GIL_DEFAULT) {
3469
        SetFlagObj(Py_NewRef(Py_None));
3470
    }
3471
    else {
3472
        SetFlag(config->enable_gil);
3473
    }
3474
#else
3475
56
    SetFlagObj(PyLong_FromLong(1));
3476
56
#endif
3477
56
    SetFlag(config->thread_inherit_context);
3478
56
    SetFlag(config->context_aware_warnings);
3479
56
#undef SetFlagObj
3480
56
#undef SetFlag
3481
56
    return 0;
3482
56
}
3483
3484
3485
static PyObject*
3486
make_flags(PyInterpreterState *interp)
3487
28
{
3488
28
    PyObject *flags = PyStructSequence_New(&FlagsType);
3489
28
    if (flags == NULL) {
3490
0
        return NULL;
3491
0
    }
3492
3493
28
    if (set_flags_from_config(interp, flags) < 0) {
3494
0
        Py_DECREF(flags);
3495
0
        return NULL;
3496
0
    }
3497
28
    return flags;
3498
28
}
3499
3500
3501
PyDoc_STRVAR(version_info__doc__,
3502
"sys.version_info\n\
3503
\n\
3504
Version information as a named tuple.");
3505
3506
static PyTypeObject VersionInfoType;
3507
3508
static PyStructSequence_Field version_info_fields[] = {
3509
    {"major", "Major release number"},
3510
    {"minor", "Minor release number"},
3511
    {"micro", "Patch release number"},
3512
    {"releaselevel", "'alpha', 'beta', 'candidate', or 'final'"},
3513
    {"serial", "Serial release number"},
3514
    {0}
3515
};
3516
3517
static PyStructSequence_Desc version_info_desc = {
3518
    "sys.version_info",     /* name */
3519
    version_info__doc__,    /* doc */
3520
    version_info_fields,    /* fields */
3521
    5
3522
};
3523
3524
static PyObject *
3525
make_version_info(PyThreadState *tstate)
3526
28
{
3527
28
    PyObject *version_info;
3528
28
    char *s;
3529
28
    int pos = 0;
3530
3531
28
    version_info = PyStructSequence_New(&VersionInfoType);
3532
28
    if (version_info == NULL) {
3533
0
        return NULL;
3534
0
    }
3535
3536
    /*
3537
     * These release level checks are mutually exclusive and cover
3538
     * the field, so don't get too fancy with the pre-processor!
3539
     */
3540
28
#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
3541
28
    s = "alpha";
3542
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
3543
    s = "beta";
3544
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
3545
    s = "candidate";
3546
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
3547
    s = "final";
3548
#endif
3549
3550
28
#define SetIntItem(flag) \
3551
112
    PyStructSequence_SET_ITEM(version_info, pos++, PyLong_FromLong(flag))
3552
28
#define SetStrItem(flag) \
3553
28
    PyStructSequence_SET_ITEM(version_info, pos++, PyUnicode_FromString(flag))
3554
3555
28
    SetIntItem(PY_MAJOR_VERSION);
3556
28
    SetIntItem(PY_MINOR_VERSION);
3557
28
    SetIntItem(PY_MICRO_VERSION);
3558
28
    SetStrItem(s);
3559
28
    SetIntItem(PY_RELEASE_SERIAL);
3560
28
#undef SetIntItem
3561
28
#undef SetStrItem
3562
3563
28
    if (_PyErr_Occurred(tstate)) {
3564
0
        Py_CLEAR(version_info);
3565
0
        return NULL;
3566
0
    }
3567
28
    return version_info;
3568
28
}
3569
3570
/* sys.implementation values */
3571
#define NAME "cpython"
3572
const char *_PySys_ImplName = NAME;
3573
#define MAJOR Py_STRINGIFY(PY_MAJOR_VERSION)
3574
#define MINOR Py_STRINGIFY(PY_MINOR_VERSION)
3575
#define TAG NAME "-" MAJOR MINOR
3576
const char *_PySys_ImplCacheTag = TAG;
3577
#undef NAME
3578
#undef MAJOR
3579
#undef MINOR
3580
#undef TAG
3581
3582
static PyObject *
3583
make_impl_info(PyObject *version_info)
3584
28
{
3585
28
    int res;
3586
28
    PyObject *impl_info, *value, *ns;
3587
3588
28
    impl_info = PyDict_New();
3589
28
    if (impl_info == NULL)
3590
0
        return NULL;
3591
3592
    /* populate the dict */
3593
3594
28
    value = PyUnicode_FromString(_PySys_ImplName);
3595
28
    if (value == NULL)
3596
0
        goto error;
3597
28
    res = PyDict_SetItemString(impl_info, "name", value);
3598
28
    Py_DECREF(value);
3599
28
    if (res < 0)
3600
0
        goto error;
3601
3602
28
    value = PyUnicode_FromString(_PySys_ImplCacheTag);
3603
28
    if (value == NULL)
3604
0
        goto error;
3605
28
    res = PyDict_SetItemString(impl_info, "cache_tag", value);
3606
28
    Py_DECREF(value);
3607
28
    if (res < 0)
3608
0
        goto error;
3609
3610
28
    res = PyDict_SetItemString(impl_info, "version", version_info);
3611
28
    if (res < 0)
3612
0
        goto error;
3613
3614
28
    value = PyLong_FromLong(PY_VERSION_HEX);
3615
28
    if (value == NULL)
3616
0
        goto error;
3617
28
    res = PyDict_SetItemString(impl_info, "hexversion", value);
3618
28
    Py_DECREF(value);
3619
28
    if (res < 0)
3620
0
        goto error;
3621
3622
28
#ifdef MULTIARCH
3623
28
    value = PyUnicode_FromString(MULTIARCH);
3624
28
    if (value == NULL)
3625
0
        goto error;
3626
28
    res = PyDict_SetItemString(impl_info, "_multiarch", value);
3627
28
    Py_DECREF(value);
3628
28
    if (res < 0)
3629
0
        goto error;
3630
28
#endif
3631
3632
    // PEP-734
3633
#if defined(__wasi__) || defined(__EMSCRIPTEN__)
3634
    // It is not enabled on WASM builds just yet
3635
    value = Py_False;
3636
#else
3637
28
    value = Py_True;
3638
28
#endif
3639
28
    res = PyDict_SetItemString(impl_info, "supports_isolated_interpreters", value);
3640
28
    if (res < 0) {
3641
0
        goto error;
3642
0
    }
3643
3644
    /* dict ready */
3645
3646
28
    ns = _PyNamespace_New(impl_info);
3647
28
    Py_DECREF(impl_info);
3648
28
    return ns;
3649
3650
0
error:
3651
0
    Py_CLEAR(impl_info);
3652
0
    return NULL;
3653
28
}
3654
3655
3656
static PyObject *
3657
make_abi_info(void)
3658
28
{
3659
    // New entries should be added when needed for a supported platform,
3660
    // or by core dev consensus for enabling an unsupported one.
3661
3662
28
    PyObject *value;
3663
28
    PyObject *abi_info = PyDict_New();
3664
28
    if (abi_info == NULL) {
3665
0
        return NULL;
3666
0
    }
3667
3668
28
    value = PyLong_FromLong(sizeof(void *) * 8);
3669
28
    if (value == NULL) {
3670
0
        goto error;
3671
0
    }
3672
28
    if (PyDict_SetItem(abi_info, &_Py_ID(pointer_bits), value) < 0) {
3673
0
        goto error;
3674
0
    }
3675
28
    Py_DECREF(value);
3676
3677
#ifdef Py_GIL_DISABLED
3678
    value = Py_True;
3679
#else
3680
28
    value = Py_False;
3681
28
#endif
3682
28
    if (PyDict_SetItem(abi_info, &_Py_ID(free_threaded), value) < 0) {
3683
0
        goto error;
3684
0
    }
3685
3686
#ifdef Py_DEBUG
3687
    value = Py_True;
3688
#else
3689
28
    value = Py_False;
3690
28
#endif
3691
28
    if (PyDict_SetItem(abi_info, &_Py_ID(debug), value) < 0) {
3692
0
        goto error;
3693
0
    }
3694
3695
#if PY_BIG_ENDIAN
3696
    value = &_Py_ID(big);
3697
#else
3698
28
    value = &_Py_ID(little);
3699
28
#endif
3700
28
    if (PyDict_SetItem(abi_info, &_Py_ID(byteorder), value) < 0) {
3701
0
        goto error;
3702
0
    }
3703
3704
28
    PyObject *ns = _PyNamespace_New(abi_info);
3705
28
    Py_DECREF(abi_info);
3706
28
    return ns;
3707
3708
0
error:
3709
0
    Py_DECREF(abi_info);
3710
0
    Py_XDECREF(value);
3711
0
    return NULL;
3712
28
}
3713
3714
3715
#ifdef __EMSCRIPTEN__
3716
3717
PyDoc_STRVAR(emscripten_info__doc__,
3718
"sys._emscripten_info\n\
3719
\n\
3720
WebAssembly Emscripten platform information.");
3721
3722
static PyTypeObject *EmscriptenInfoType;
3723
3724
static PyStructSequence_Field emscripten_info_fields[] = {
3725
    {"emscripten_version", "Emscripten version (major, minor, micro)"},
3726
    {"runtime", "Runtime (Node.JS version, browser user agent)"},
3727
    {"pthreads", "pthread support"},
3728
    {"shared_memory", "shared memory support"},
3729
    {0}
3730
};
3731
3732
static PyStructSequence_Desc emscripten_info_desc = {
3733
    "sys._emscripten_info",     /* name */
3734
    emscripten_info__doc__ ,    /* doc */
3735
    emscripten_info_fields,     /* fields */
3736
    4
3737
};
3738
3739
EM_JS(char *, _Py_emscripten_runtime, (void), {
3740
    var info;
3741
    if (typeof navigator == 'object') {
3742
        info = navigator.userAgent;
3743
    } else if (typeof process == 'object') {
3744
        info = "Node.js ".concat(process.version);
3745
    } else {
3746
        info = "UNKNOWN";
3747
    }
3748
    var len = lengthBytesUTF8(info) + 1;
3749
    var res = _malloc(len);
3750
    if (res) stringToUTF8(info, res, len);
3751
#if __wasm64__
3752
    return BigInt(res);
3753
#else
3754
    return res;
3755
#endif
3756
});
3757
3758
static PyObject *
3759
make_emscripten_info(void)
3760
{
3761
    PyObject *emscripten_info = NULL;
3762
    PyObject *version = NULL;
3763
    char *ua;
3764
    int pos = 0;
3765
3766
    emscripten_info = PyStructSequence_New(EmscriptenInfoType);
3767
    if (emscripten_info == NULL) {
3768
        return NULL;
3769
    }
3770
3771
    version = Py_BuildValue("(iii)",
3772
        __EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__);
3773
    if (version == NULL) {
3774
        goto error;
3775
    }
3776
    PyStructSequence_SET_ITEM(emscripten_info, pos++, version);
3777
3778
    ua = _Py_emscripten_runtime();
3779
    if (ua != NULL) {
3780
        PyObject *oua = PyUnicode_DecodeUTF8(ua, strlen(ua), "strict");
3781
        free(ua);
3782
        if (oua == NULL) {
3783
            goto error;
3784
        }
3785
        PyStructSequence_SET_ITEM(emscripten_info, pos++, oua);
3786
    } else {
3787
        PyStructSequence_SET_ITEM(emscripten_info, pos++, Py_NewRef(Py_None));
3788
    }
3789
3790
#define SetBoolItem(flag) \
3791
    PyStructSequence_SET_ITEM(emscripten_info, pos++, PyBool_FromLong(flag))
3792
3793
#ifdef __EMSCRIPTEN_PTHREADS__
3794
    SetBoolItem(1);
3795
#else
3796
    SetBoolItem(0);
3797
#endif
3798
3799
#ifdef __EMSCRIPTEN_SHARED_MEMORY__
3800
    SetBoolItem(1);
3801
#else
3802
    SetBoolItem(0);
3803
#endif
3804
3805
#undef SetBoolItem
3806
3807
    if (PyErr_Occurred()) {
3808
        goto error;
3809
    }
3810
    return emscripten_info;
3811
3812
  error:
3813
    Py_CLEAR(emscripten_info);
3814
    return NULL;
3815
}
3816
3817
#endif // __EMSCRIPTEN__
3818
3819
static struct PyModuleDef sysmodule = {
3820
    PyModuleDef_HEAD_INIT,
3821
    "sys",
3822
    sys_doc,
3823
    -1, /* multiple "initialization" just copies the module dict. */
3824
    sys_methods,
3825
    NULL,
3826
    NULL,
3827
    NULL,
3828
    NULL
3829
};
3830
3831
/* Updating the sys namespace, returning NULL pointer on error */
3832
#define SET_SYS(key, value)                                \
3833
1.20k
    do {                                                   \
3834
1.20k
        PyObject *v = (value);                             \
3835
1.20k
        if (v == NULL) {                                   \
3836
0
            goto err_occurred;                             \
3837
0
        }                                                  \
3838
1.20k
        res = PyDict_SetItemString(sysdict, key, v);       \
3839
1.20k
        Py_DECREF(v);                                      \
3840
1.20k
        if (res < 0) {                                     \
3841
0
            goto err_occurred;                             \
3842
0
        }                                                  \
3843
1.20k
    } while (0)
3844
3845
#define SET_SYS_FROM_STRING(key, value) \
3846
140
        SET_SYS(key, PyUnicode_FromString(value))
3847
3848
static PyStatus
3849
_PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
3850
28
{
3851
28
    PyObject *version_info;
3852
28
    int res;
3853
28
    PyInterpreterState *interp = tstate->interp;
3854
3855
    /* stdin/stdout/stderr are set in pylifecycle.c */
3856
3857
28
#define COPY_SYS_ATTR(tokey, fromkey) \
3858
112
        SET_SYS(tokey, PyMapping_GetItemString(sysdict, fromkey))
3859
3860
28
    COPY_SYS_ATTR("__displayhook__", "displayhook");
3861
28
    COPY_SYS_ATTR("__excepthook__", "excepthook");
3862
28
    COPY_SYS_ATTR("__breakpointhook__", "breakpointhook");
3863
28
    COPY_SYS_ATTR("__unraisablehook__", "unraisablehook");
3864
3865
28
#undef COPY_SYS_ATTR
3866
3867
28
    SET_SYS_FROM_STRING("version", Py_GetVersion());
3868
28
    SET_SYS("hexversion", PyLong_FromLong(PY_VERSION_HEX));
3869
28
    SET_SYS("_git", Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(),
3870
28
                                  _Py_gitversion()));
3871
28
    SET_SYS_FROM_STRING("_framework", _PYTHONFRAMEWORK);
3872
28
    SET_SYS("api_version", PyLong_FromLong(PYTHON_API_VERSION));
3873
28
    SET_SYS_FROM_STRING("copyright", Py_GetCopyright());
3874
28
    SET_SYS_FROM_STRING("platform", Py_GetPlatform());
3875
28
    SET_SYS("maxsize", PyLong_FromSsize_t(PY_SSIZE_T_MAX));
3876
28
    SET_SYS("float_info", PyFloat_GetInfo());
3877
28
    SET_SYS("int_info", PyLong_GetInfo());
3878
    /* initialize hash_info */
3879
28
    if (_PyStructSequence_InitBuiltin(interp, &Hash_InfoType,
3880
28
                                      &hash_info_desc) < 0)
3881
0
    {
3882
0
        goto type_init_failed;
3883
0
    }
3884
28
    SET_SYS("hash_info", get_hash_info(tstate));
3885
28
    SET_SYS("maxunicode", PyLong_FromLong(0x10FFFF));
3886
28
    SET_SYS("builtin_module_names", list_builtin_module_names());
3887
28
    SET_SYS("stdlib_module_names", list_stdlib_module_names());
3888
#if PY_BIG_ENDIAN
3889
    SET_SYS("byteorder", &_Py_ID(big));
3890
#else
3891
28
    SET_SYS("byteorder", &_Py_ID(little));
3892
28
#endif
3893
3894
#ifdef MS_COREDLL
3895
    SET_SYS("dllhandle", PyLong_FromVoidPtr(PyWin_DLLhModule));
3896
    SET_SYS_FROM_STRING("winver", PyWin_DLLVersionString);
3897
#endif
3898
28
#ifdef ABIFLAGS
3899
28
    SET_SYS_FROM_STRING("abiflags", ABIFLAGS);
3900
28
#endif
3901
3902
28
#define ENSURE_INFO_TYPE(TYPE, DESC) \
3903
56
    do { \
3904
56
        if (_PyStructSequence_InitBuiltinWithFlags( \
3905
56
                interp, &TYPE, &DESC, Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { \
3906
0
            goto type_init_failed; \
3907
0
        } \
3908
56
    } while (0)
3909
3910
    /* version_info */
3911
28
    ENSURE_INFO_TYPE(VersionInfoType, version_info_desc);
3912
28
    version_info = make_version_info(tstate);
3913
28
    SET_SYS("version_info", version_info);
3914
3915
    /* implementation */
3916
28
    SET_SYS("implementation", make_impl_info(version_info));
3917
3918
    // sys.flags: updated in-place later by _PySys_UpdateConfig()
3919
28
    ENSURE_INFO_TYPE(FlagsType, flags_desc);
3920
28
    SET_SYS("flags", make_flags(tstate->interp));
3921
3922
#if defined(MS_WINDOWS)
3923
    /* getwindowsversion */
3924
    ENSURE_INFO_TYPE(WindowsVersionType, windows_version_desc);
3925
3926
    SET_SYS_FROM_STRING("_vpath", VPATH);
3927
#endif
3928
3929
28
#undef ENSURE_INFO_TYPE
3930
3931
    /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */
3932
28
#if _PY_SHORT_FLOAT_REPR == 1
3933
28
    SET_SYS("float_repr_style", &_Py_ID(short));
3934
#else
3935
    SET_SYS("float_repr_style", &_Py_ID(legacy));
3936
#endif
3937
3938
28
    SET_SYS("thread_info", PyThread_GetInfo());
3939
3940
28
    SET_SYS("abi_info", make_abi_info());
3941
3942
    /* initialize asyncgen_hooks */
3943
28
    if (_PyStructSequence_InitBuiltin(interp, &AsyncGenHooksType,
3944
28
                                      &asyncgen_hooks_desc) < 0)
3945
0
    {
3946
0
        goto type_init_failed;
3947
0
    }
3948
3949
#ifdef __EMSCRIPTEN__
3950
    if (EmscriptenInfoType == NULL) {
3951
        EmscriptenInfoType = PyStructSequence_NewType(&emscripten_info_desc);
3952
        if (EmscriptenInfoType == NULL) {
3953
            goto type_init_failed;
3954
        }
3955
    }
3956
    SET_SYS("_emscripten_info", make_emscripten_info());
3957
#endif
3958
3959
    /* adding sys.path_hooks and sys.path_importer_cache */
3960
28
    SET_SYS("meta_path", PyList_New(0));
3961
28
    SET_SYS("path_importer_cache", PyDict_New());
3962
28
    SET_SYS("path_hooks", PyList_New(0));
3963
3964
28
    if (_PyErr_Occurred(tstate)) {
3965
0
        goto err_occurred;
3966
0
    }
3967
28
    return _PyStatus_OK();
3968
3969
0
type_init_failed:
3970
0
    return _PyStatus_ERR("failed to initialize a type");
3971
3972
0
err_occurred:
3973
0
    return _PyStatus_ERR("can't initialize sys module");
3974
28
}
3975
3976
3977
// Update sys attributes for a new PyConfig configuration.
3978
// This function also adds attributes that _PySys_InitCore() didn't add.
3979
int
3980
_PySys_UpdateConfig(PyThreadState *tstate)
3981
28
{
3982
28
    PyInterpreterState *interp = tstate->interp;
3983
28
    PyObject *sysdict = interp->sysdict;
3984
28
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);
3985
28
    int res;
3986
3987
28
#define COPY_LIST(KEY, VALUE) \
3988
112
        SET_SYS(KEY, _PyWideStringList_AsList(&(VALUE)));
3989
3990
28
#define SET_SYS_FROM_WSTR(KEY, VALUE) \
3991
224
        SET_SYS(KEY, PyUnicode_FromWideChar(VALUE, -1));
3992
3993
28
#define COPY_WSTR(SYS_ATTR, WSTR) \
3994
196
    if (WSTR != NULL) { \
3995
196
        SET_SYS_FROM_WSTR(SYS_ATTR, WSTR); \
3996
196
    }
3997
3998
28
    if (config->module_search_paths_set) {
3999
28
        COPY_LIST("path", config->module_search_paths);
4000
28
    }
4001
4002
28
    COPY_WSTR("executable", config->executable);
4003
28
    COPY_WSTR("_base_executable", config->base_executable);
4004
28
    COPY_WSTR("prefix", config->prefix);
4005
28
    COPY_WSTR("base_prefix", config->base_prefix);
4006
28
    COPY_WSTR("exec_prefix", config->exec_prefix);
4007
28
    COPY_WSTR("base_exec_prefix", config->base_exec_prefix);
4008
28
    COPY_WSTR("platlibdir", config->platlibdir);
4009
4010
28
    if (config->pycache_prefix != NULL) {
4011
0
        SET_SYS_FROM_WSTR("pycache_prefix", config->pycache_prefix);
4012
28
    } else {
4013
28
        if (PyDict_SetItemString(sysdict, "pycache_prefix", Py_None) < 0) {
4014
0
            return -1;
4015
0
        }
4016
28
    }
4017
4018
28
    COPY_LIST("argv", config->argv);
4019
28
    COPY_LIST("orig_argv", config->orig_argv);
4020
28
    COPY_LIST("warnoptions", config->warnoptions);
4021
4022
28
    SET_SYS("_xoptions", _PyConfig_CreateXOptionsDict(config));
4023
4024
28
    const wchar_t *stdlibdir = _Py_GetStdlibDir();
4025
28
    if (stdlibdir != NULL) {
4026
28
        SET_SYS_FROM_WSTR("_stdlib_dir", stdlibdir);
4027
28
    }
4028
0
    else {
4029
0
        if (PyDict_SetItemString(sysdict, "_stdlib_dir", Py_None) < 0) {
4030
0
            return -1;
4031
0
        }
4032
0
    }
4033
4034
28
#undef SET_SYS_FROM_WSTR
4035
28
#undef COPY_LIST
4036
28
#undef COPY_WSTR
4037
4038
    // sys.flags
4039
28
    PyObject *flags = PySys_GetAttrString("flags");
4040
28
    if (flags == NULL) {
4041
0
        return -1;
4042
0
    }
4043
28
    if (set_flags_from_config(interp, flags) < 0) {
4044
0
        Py_DECREF(flags);
4045
0
        return -1;
4046
0
    }
4047
28
    Py_DECREF(flags);
4048
4049
28
    SET_SYS("dont_write_bytecode", PyBool_FromLong(!config->write_bytecode));
4050
4051
28
    if (_PyErr_Occurred(tstate)) {
4052
0
        goto err_occurred;
4053
0
    }
4054
4055
28
    return 0;
4056
4057
0
err_occurred:
4058
0
    return -1;
4059
28
}
4060
4061
#undef SET_SYS
4062
#undef SET_SYS_FROM_STRING
4063
4064
4065
/* Set up a preliminary stderr printer until we have enough
4066
   infrastructure for the io module in place.
4067
4068
   Use UTF-8/backslashreplace and ignore EAGAIN errors. */
4069
static PyStatus
4070
_PySys_SetPreliminaryStderr(PyObject *sysdict)
4071
28
{
4072
28
    PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr));
4073
28
    if (pstderr == NULL) {
4074
0
        goto error;
4075
0
    }
4076
28
    if (PyDict_SetItem(sysdict, &_Py_ID(stderr), pstderr) < 0) {
4077
0
        goto error;
4078
0
    }
4079
28
    if (PyDict_SetItemString(sysdict, "__stderr__", pstderr) < 0) {
4080
0
        goto error;
4081
0
    }
4082
28
    Py_DECREF(pstderr);
4083
28
    return _PyStatus_OK();
4084
4085
0
error:
4086
0
    Py_XDECREF(pstderr);
4087
0
    return _PyStatus_ERR("can't set preliminary stderr");
4088
28
}
4089
4090
PyObject *_Py_CreateMonitoringObject(void);
4091
4092
/*[clinic input]
4093
module _jit
4094
[clinic start generated code]*/
4095
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=10952f74d7bbd972]*/
4096
4097
PyDoc_STRVAR(_jit_doc, "Utilities for observing just-in-time compilation.");
4098
4099
/*[clinic input]
4100
@permit_long_summary
4101
_jit.is_available -> bool
4102
Return True if the current Python executable supports JIT compilation, and False otherwise.
4103
[clinic start generated code]*/
4104
4105
static int
4106
_jit_is_available_impl(PyObject *module)
4107
/*[clinic end generated code: output=6849a9cd2ff4aac9 input=d009d751ae64c9ef]*/
4108
0
{
4109
0
    (void)module;
4110
#ifdef _Py_TIER2
4111
    return true;
4112
#else
4113
0
    return false;
4114
0
#endif
4115
0
}
4116
4117
/*[clinic input]
4118
@permit_long_summary
4119
_jit.is_enabled -> bool
4120
Return True if JIT compilation is enabled for the current Python process (implies sys._jit.is_available()), and False otherwise.
4121
[clinic start generated code]*/
4122
4123
static int
4124
_jit_is_enabled_impl(PyObject *module)
4125
/*[clinic end generated code: output=55865f8de993fe42 input=0524151e857f4f3a]*/
4126
0
{
4127
0
    (void)module;
4128
0
    return _PyInterpreterState_GET()->jit;
4129
0
}
4130
4131
/*[clinic input]
4132
@permit_long_summary
4133
_jit.is_active -> bool
4134
Return True if the topmost Python frame is currently executing JIT code (implies sys._jit.is_enabled()), and False otherwise.
4135
[clinic start generated code]*/
4136
4137
static int
4138
_jit_is_active_impl(PyObject *module)
4139
/*[clinic end generated code: output=7facca06b10064d4 input=081ee32563dc2086]*/
4140
0
{
4141
0
    (void)module;
4142
0
    return _PyThreadState_GET()->current_executor != NULL;
4143
0
}
4144
4145
static PyMethodDef _jit_methods[] = {
4146
    _JIT_IS_AVAILABLE_METHODDEF
4147
    _JIT_IS_ENABLED_METHODDEF
4148
    _JIT_IS_ACTIVE_METHODDEF
4149
    {NULL}
4150
};
4151
4152
static struct PyModuleDef _jit_module = {
4153
    PyModuleDef_HEAD_INIT,
4154
    .m_name = "sys._jit",
4155
    .m_doc = _jit_doc,
4156
    .m_size = -1,
4157
    .m_methods = _jit_methods,
4158
};
4159
4160
/* Create sys module without all attributes.
4161
   _PySys_UpdateConfig() should be called later to add remaining attributes. */
4162
PyStatus
4163
_PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
4164
28
{
4165
28
    assert(!_PyErr_Occurred(tstate));
4166
4167
28
    PyInterpreterState *interp = tstate->interp;
4168
4169
28
    PyObject *modules = _PyImport_InitModules(interp);
4170
28
    if (modules == NULL) {
4171
0
        goto error;
4172
0
    }
4173
4174
28
    PyObject *sysmod = _PyModule_CreateInitialized(&sysmodule, PYTHON_API_VERSION);
4175
28
    if (sysmod == NULL) {
4176
0
        return _PyStatus_ERR("failed to create a module object");
4177
0
    }
4178
#ifdef Py_GIL_DISABLED
4179
    PyUnstable_Module_SetGIL(sysmod, Py_MOD_GIL_NOT_USED);
4180
#endif
4181
4182
28
    PyObject *sysdict = PyModule_GetDict(sysmod);
4183
28
    if (sysdict == NULL) {
4184
0
        goto error;
4185
0
    }
4186
28
    interp->sysdict = Py_NewRef(sysdict);
4187
4188
28
    interp->sysdict_copy = PyDict_Copy(sysdict);
4189
28
    if (interp->sysdict_copy == NULL) {
4190
0
        goto error;
4191
0
    }
4192
4193
28
    if (PyDict_SetItemString(sysdict, "modules", modules) < 0) {
4194
0
        goto error;
4195
0
    }
4196
4197
28
    PyStatus status = _PySys_SetPreliminaryStderr(sysdict);
4198
28
    if (_PyStatus_EXCEPTION(status)) {
4199
0
        return status;
4200
0
    }
4201
4202
28
    status = _PySys_InitCore(tstate, sysdict);
4203
28
    if (_PyStatus_EXCEPTION(status)) {
4204
0
        return status;
4205
0
    }
4206
4207
28
    if (_PyImport_FixupBuiltin(tstate, sysmod, "sys", modules) < 0) {
4208
0
        goto error;
4209
0
    }
4210
4211
28
    PyObject *monitoring = _Py_CreateMonitoringObject();
4212
28
    if (monitoring == NULL) {
4213
0
        goto error;
4214
0
    }
4215
28
    int err = PyDict_SetItemString(sysdict, "monitoring", monitoring);
4216
28
    Py_DECREF(monitoring);
4217
28
    if (err < 0) {
4218
0
        goto error;
4219
0
    }
4220
4221
28
    PyObject *_jit = _PyModule_CreateInitialized(&_jit_module, PYTHON_API_VERSION);
4222
28
    if (_jit == NULL) {
4223
0
        goto error;
4224
0
    }
4225
28
    err = PyDict_SetItemString(sysdict, "_jit", _jit);
4226
28
    Py_DECREF(_jit);
4227
28
    if (err) {
4228
0
        goto error;
4229
0
    }
4230
4231
28
    assert(!_PyErr_Occurred(tstate));
4232
4233
28
    *sysmod_p = sysmod;
4234
28
    return _PyStatus_OK();
4235
4236
0
error:
4237
0
    return _PyStatus_ERR("can't initialize sys module");
4238
28
}
4239
4240
4241
void
4242
_PySys_FiniTypes(PyInterpreterState *interp)
4243
0
{
4244
0
    _PyStructSequence_FiniBuiltin(interp, &VersionInfoType);
4245
0
    _PyStructSequence_FiniBuiltin(interp, &FlagsType);
4246
#if defined(MS_WINDOWS)
4247
    _PyStructSequence_FiniBuiltin(interp, &WindowsVersionType);
4248
#endif
4249
0
    _PyStructSequence_FiniBuiltin(interp, &Hash_InfoType);
4250
0
    _PyStructSequence_FiniBuiltin(interp, &AsyncGenHooksType);
4251
#ifdef __EMSCRIPTEN__
4252
    if (_Py_IsMainInterpreter(interp)) {
4253
        Py_CLEAR(EmscriptenInfoType);
4254
    }
4255
#endif
4256
0
}
4257
4258
4259
static PyObject *
4260
makepathobject(const wchar_t *path, wchar_t delim)
4261
0
{
4262
0
    int i, n;
4263
0
    const wchar_t *p;
4264
0
    PyObject *v, *w;
4265
4266
0
    n = 1;
4267
0
    p = path;
4268
0
    while ((p = wcschr(p, delim)) != NULL) {
4269
0
        n++;
4270
0
        p++;
4271
0
    }
4272
0
    v = PyList_New(n);
4273
0
    if (v == NULL)
4274
0
        return NULL;
4275
0
    for (i = 0; ; i++) {
4276
0
        p = wcschr(path, delim);
4277
0
        if (p == NULL)
4278
0
            p = path + wcslen(path); /* End of string */
4279
0
        w = PyUnicode_FromWideChar(path, (Py_ssize_t)(p - path));
4280
0
        if (w == NULL) {
4281
0
            Py_DECREF(v);
4282
0
            return NULL;
4283
0
        }
4284
0
        PyList_SET_ITEM(v, i, w);
4285
0
        if (*p == '\0')
4286
0
            break;
4287
0
        path = p+1;
4288
0
    }
4289
0
    return v;
4290
0
}
4291
4292
// Removed in Python 3.13 API, but kept for the stable ABI
4293
PyAPI_FUNC(void)
4294
PySys_SetPath(const wchar_t *path)
4295
0
{
4296
0
    PyObject *v;
4297
0
    if ((v = makepathobject(path, DELIM)) == NULL)
4298
0
        Py_FatalError("can't create sys.path");
4299
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
4300
0
    if (sys_set_object(interp, &_Py_ID(path), v) != 0) {
4301
0
        Py_FatalError("can't assign sys.path");
4302
0
    }
4303
0
    Py_DECREF(v);
4304
0
}
4305
4306
static PyObject *
4307
make_sys_argv(int argc, wchar_t * const * argv)
4308
0
{
4309
0
    PyObject *list = PyList_New(argc);
4310
0
    if (list == NULL) {
4311
0
        return NULL;
4312
0
    }
4313
4314
0
    for (Py_ssize_t i = 0; i < argc; i++) {
4315
0
        PyObject *v = PyUnicode_FromWideChar(argv[i], -1);
4316
0
        if (v == NULL) {
4317
0
            Py_DECREF(list);
4318
0
            return NULL;
4319
0
        }
4320
0
        PyList_SET_ITEM(list, i, v);
4321
0
    }
4322
0
    return list;
4323
0
}
4324
4325
void
4326
PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
4327
0
{
4328
0
    wchar_t* empty_argv[1] = {L""};
4329
0
    PyThreadState *tstate = _PyThreadState_GET();
4330
4331
0
    if (argc < 1 || argv == NULL) {
4332
        /* Ensure at least one (empty) argument is seen */
4333
0
        argv = empty_argv;
4334
0
        argc = 1;
4335
0
    }
4336
4337
0
    PyObject *av = make_sys_argv(argc, argv);
4338
0
    if (av == NULL) {
4339
0
        Py_FatalError("no mem for sys.argv");
4340
0
    }
4341
0
    if (sys_set_object_str(tstate->interp, "argv", av) != 0) {
4342
0
        Py_DECREF(av);
4343
0
        Py_FatalError("can't assign sys.argv");
4344
0
    }
4345
0
    Py_DECREF(av);
4346
4347
0
    if (updatepath) {
4348
        /* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path.
4349
           If argv[0] is a symlink, use the real path. */
4350
0
        const PyWideStringList argv_list = {.length = argc, .items = argv};
4351
0
        PyObject *path0 = NULL;
4352
0
        if (_PyPathConfig_ComputeSysPath0(&argv_list, &path0)) {
4353
0
            if (path0 == NULL) {
4354
0
                Py_FatalError("can't compute path0 from argv");
4355
0
            }
4356
4357
0
            PyObject *sys_path;
4358
0
            if (PySys_GetOptionalAttr(&_Py_ID(path), &sys_path) < 0) {
4359
0
                Py_FatalError("can't get sys.path");
4360
0
            }
4361
0
            else if (sys_path != NULL) {
4362
0
                if (PyList_Insert(sys_path, 0, path0) < 0) {
4363
0
                    Py_FatalError("can't prepend path0 to sys.path");
4364
0
                }
4365
0
                Py_DECREF(sys_path);
4366
0
            }
4367
0
            Py_DECREF(path0);
4368
0
        }
4369
0
    }
4370
0
}
4371
4372
void
4373
PySys_SetArgv(int argc, wchar_t **argv)
4374
0
{
4375
0
_Py_COMP_DIAG_PUSH
4376
0
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
4377
0
    PySys_SetArgvEx(argc, argv, Py_IsolatedFlag == 0);
4378
0
_Py_COMP_DIAG_POP
4379
0
}
4380
4381
/* Reimplementation of PyFile_WriteString() no calling indirectly
4382
   PyErr_CheckSignals(): avoid the call to PyObject_Str(). */
4383
4384
static int
4385
sys_pyfile_write_unicode(PyObject *unicode, PyObject *file)
4386
0
{
4387
0
    if (file == NULL)
4388
0
        return -1;
4389
0
    assert(unicode != NULL);
4390
0
    PyObject *result = PyObject_CallMethodOneArg(file, &_Py_ID(write), unicode);
4391
0
    if (result == NULL) {
4392
0
        return -1;
4393
0
    }
4394
0
    Py_DECREF(result);
4395
0
    return 0;
4396
0
}
4397
4398
static int
4399
sys_pyfile_write(const char *text, PyObject *file)
4400
0
{
4401
0
    PyObject *unicode = NULL;
4402
0
    int err;
4403
4404
0
    if (file == NULL)
4405
0
        return -1;
4406
4407
0
    unicode = PyUnicode_FromString(text);
4408
0
    if (unicode == NULL)
4409
0
        return -1;
4410
4411
0
    err = sys_pyfile_write_unicode(unicode, file);
4412
0
    Py_DECREF(unicode);
4413
0
    return err;
4414
0
}
4415
4416
/* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
4417
   Adapted from code submitted by Just van Rossum.
4418
4419
   PySys_WriteStdout(format, ...)
4420
   PySys_WriteStderr(format, ...)
4421
4422
      The first function writes to sys.stdout; the second to sys.stderr.  When
4423
      there is a problem, they write to the real (C level) stdout or stderr;
4424
      no exceptions are raised.
4425
4426
      PyErr_CheckSignals() is not called to avoid the execution of the Python
4427
      signal handlers: they may raise a new exception whereas sys_write()
4428
      ignores all exceptions.
4429
4430
      Both take a printf-style format string as their first argument followed
4431
      by a variable length argument list determined by the format string.
4432
4433
      *** WARNING ***
4434
4435
      The format should limit the total size of the formatted output string to
4436
      1000 bytes.  In particular, this means that no unrestricted "%s" formats
4437
      should occur; these should be limited using "%.<N>s where <N> is a
4438
      decimal number calculated so that <N> plus the maximum size of other
4439
      formatted text does not exceed 1000 bytes.  Also watch out for "%f",
4440
      which can print hundreds of digits for very large numbers.
4441
4442
 */
4443
4444
static void
4445
sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
4446
0
{
4447
0
    PyObject *file;
4448
0
    char buffer[1001];
4449
0
    int written;
4450
0
    PyThreadState *tstate = _PyThreadState_GET();
4451
4452
0
    PyObject *exc = _PyErr_GetRaisedException(tstate);
4453
0
    written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
4454
0
    file = PySys_GetAttr(key);
4455
0
    if (sys_pyfile_write(buffer, file) != 0) {
4456
0
        _PyErr_Clear(tstate);
4457
0
        fputs(buffer, fp);
4458
0
    }
4459
0
    if (written < 0 || (size_t)written >= sizeof(buffer)) {
4460
0
        const char *truncated = "... truncated";
4461
0
        if (sys_pyfile_write(truncated, file) != 0)
4462
0
            fputs(truncated, fp);
4463
0
    }
4464
0
    Py_XDECREF(file);
4465
0
    _PyErr_SetRaisedException(tstate, exc);
4466
0
}
4467
4468
void
4469
PySys_WriteStdout(const char *format, ...)
4470
0
{
4471
0
    va_list va;
4472
4473
0
    va_start(va, format);
4474
0
    sys_write(&_Py_ID(stdout), stdout, format, va);
4475
0
    va_end(va);
4476
0
}
4477
4478
void
4479
PySys_WriteStderr(const char *format, ...)
4480
0
{
4481
0
    va_list va;
4482
4483
0
    va_start(va, format);
4484
0
    sys_write(&_Py_ID(stderr), stderr, format, va);
4485
0
    va_end(va);
4486
0
}
4487
4488
static void
4489
sys_format(PyObject *key, FILE *fp, const char *format, va_list va)
4490
0
{
4491
0
    PyObject *file, *message;
4492
0
    const char *utf8;
4493
0
    PyThreadState *tstate = _PyThreadState_GET();
4494
4495
0
    PyObject *exc = _PyErr_GetRaisedException(tstate);
4496
0
    message = PyUnicode_FromFormatV(format, va);
4497
0
    if (message != NULL) {
4498
0
        file = PySys_GetAttr(key);
4499
0
        if (sys_pyfile_write_unicode(message, file) != 0) {
4500
0
            _PyErr_Clear(tstate);
4501
0
            utf8 = PyUnicode_AsUTF8(message);
4502
0
            if (utf8 != NULL)
4503
0
                fputs(utf8, fp);
4504
0
        }
4505
0
        Py_XDECREF(file);
4506
0
        Py_DECREF(message);
4507
0
    }
4508
0
    _PyErr_SetRaisedException(tstate, exc);
4509
0
}
4510
4511
void
4512
PySys_FormatStdout(const char *format, ...)
4513
0
{
4514
0
    va_list va;
4515
4516
0
    va_start(va, format);
4517
0
    sys_format(&_Py_ID(stdout), stdout, format, va);
4518
0
    va_end(va);
4519
0
}
4520
4521
void
4522
PySys_FormatStderr(const char *format, ...)
4523
0
{
4524
0
    va_list va;
4525
4526
0
    va_start(va, format);
4527
0
    sys_format(&_Py_ID(stderr), stderr, format, va);
4528
0
    va_end(va);
4529
0
}
4530
4531
4532
int
4533
_PySys_SetIntMaxStrDigits(int maxdigits)
4534
0
{
4535
0
    if (maxdigits != 0 && maxdigits < _PY_LONG_MAX_STR_DIGITS_THRESHOLD) {
4536
0
        PyErr_Format(
4537
0
            PyExc_ValueError, "maxdigits must be >= %d or 0 for unlimited",
4538
0
            _PY_LONG_MAX_STR_DIGITS_THRESHOLD);
4539
0
        return -1;
4540
0
    }
4541
4542
    // Set sys.flags.int_max_str_digits
4543
0
    const Py_ssize_t pos = SYS_FLAGS_INT_MAX_STR_DIGITS;
4544
0
    if (_PySys_SetFlagInt(pos, maxdigits) < 0) {
4545
0
        return -1;
4546
0
    }
4547
4548
    // Set PyInterpreterState.long_state.max_str_digits
4549
    // and PyInterpreterState.config.int_max_str_digits.
4550
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
4551
0
    interp->long_state.max_str_digits = maxdigits;
4552
0
    interp->config.int_max_str_digits = maxdigits;
4553
0
    return 0;
4554
0
}