Coverage Report

Created: 2022-07-08 09:39

/home/mdboom/Work/builds/cpython/Python/sysmodule.c
Line
Count
Source (jump to first uncovered line)
1
2
/* System module */
3
4
/*
5
Various bits of information used by the interpreter are collected in
6
module 'sys'.
7
Function member:
8
- exit(sts): raise SystemExit
9
Data members:
10
- stdin, stdout, stderr: standard file objects
11
- modules: the table of modules (dictionary)
12
- path: module search path (list of strings)
13
- argv: script arguments (list of strings)
14
- ps1, ps2: optional primary and secondary prompts (strings)
15
*/
16
17
#include "Python.h"
18
#include "pycore_call.h"          // _PyObject_CallNoArgs()
19
#include "pycore_ceval.h"         // _PyEval_SetAsyncGenFinalizer()
20
#include "pycore_code.h"          // _Py_QuickenedCount
21
#include "pycore_frame.h"         // _PyInterpreterFrame
22
#include "pycore_initconfig.h"    // _PyStatus_EXCEPTION()
23
#include "pycore_namespace.h"     // _PyNamespace_New()
24
#include "pycore_object.h"        // _PyObject_IS_GC()
25
#include "pycore_pathconfig.h"    // _PyPathConfig_ComputeSysPath0()
26
#include "pycore_pyerrors.h"      // _PyErr_Fetch()
27
#include "pycore_pylifecycle.h"   // _PyErr_WriteUnraisableDefaultHook()
28
#include "pycore_pymath.h"        // _PY_SHORT_FLOAT_REPR
29
#include "pycore_pymem.h"         // _PyMem_SetDefaultAllocator()
30
#include "pycore_pystate.h"       // _PyThreadState_GET()
31
#include "pycore_structseq.h"     // _PyStructSequence_InitType()
32
#include "pycore_tuple.h"         // _PyTuple_FromArray()
33
34
#include "frameobject.h"          // PyFrame_FastToLocalsWithError()
35
#include "pydtrace.h"
36
#include "osdefs.h"               // DELIM
37
#include "stdlib_module_names.h"  // _Py_stdlib_module_names
38
#include <locale.h>
39
40
#ifdef MS_WINDOWS
41
#define WIN32_LEAN_AND_MEAN
42
#include <windows.h>
43
#endif /* MS_WINDOWS */
44
45
#ifdef MS_COREDLL
46
extern void *PyWin_DLLhModule;
47
/* A string loaded from the DLL at startup: */
48
extern const char *PyWin_DLLVersionString;
49
#endif
50
51
#ifdef __EMSCRIPTEN__
52
#include <emscripten.h>
53
#endif
54
55
/*[clinic input]
56
module sys
57
[clinic start generated code]*/
58
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3726b388feee8cea]*/
59
60
#include "clinic/sysmodule.c.h"
61
62
PyObject *
63
_PySys_GetAttr(PyThreadState *tstate, PyObject *name)
64
{
65
    PyObject *sd = tstate->interp->sysdict;
66
    if (sd == NULL) {
  Branch (66:9): [True: 4, False: 27.8k]
67
        return NULL;
68
    }
69
    PyObject *exc_type, *exc_value, *exc_tb;
70
    _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
71
    /* XXX Suppress a new exception if it was raised and restore
72
     * the old one. */
73
    PyObject *value = _PyDict_GetItemWithError(sd, name);
74
    _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
75
    return value;
76
}
77
78
static PyObject *
79
_PySys_GetObject(PyInterpreterState *interp, const char *name)
80
{
81
    PyObject *sysdict = interp->sysdict;
82
    if (sysdict == NULL) {
  Branch (82:9): [True: 0, False: 36.2k]
83
        return NULL;
84
    }
85
    return _PyDict_GetItemStringWithError(sysdict, name);
86
}
87
88
PyObject *
89
PySys_GetObject(const char *name)
90
{
91
    PyThreadState *tstate = _PyThreadState_GET();
92
93
    PyObject *exc_type, *exc_value, *exc_tb;
94
    _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
95
    PyObject *value = _PySys_GetObject(tstate->interp, name);
96
    /* XXX Suppress a new exception if it was raised and restore
97
     * the old one. */
98
    _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
99
    return value;
100
}
101
102
static int
103
sys_set_object(PyInterpreterState *interp, PyObject *key, PyObject *v)
104
{
105
    if (key == NULL) {
  Branch (105:9): [True: 0, False: 1.67k]
106
        return -1;
107
    }
108
    PyObject *sd = interp->sysdict;
109
    if (v == NULL) {
  Branch (109:9): [True: 0, False: 1.67k]
110
        v = _PyDict_Pop(sd, key, Py_None);
111
        if (v == NULL) {
  Branch (111:13): [True: 0, False: 0]
112
            return -1;
113
        }
114
        Py_DECREF(v);
115
        return 0;
116
    }
117
    else {
118
        return PyDict_SetItem(sd, key, v);
119
    }
120
}
121
122
int
123
_PySys_SetAttr(PyObject *key, PyObject *v)
124
{
125
    PyInterpreterState *interp = _PyInterpreterState_GET();
126
    return sys_set_object(interp, key, v);
127
}
128
129
static int
130
sys_set_object_str(PyInterpreterState *interp, const char *name, PyObject *v)
131
{
132
    PyObject *key = v ? PyUnicode_InternFromString(name)
  Branch (132:21): [True: 834, False: 0]
133
                      : 
PyUnicode_FromString(name)0
;
134
    int r = sys_set_object(interp, key, v);
135
    Py_XDECREF(key);
136
    return r;
137
}
138
139
int
140
PySys_SetObject(const char *name, PyObject *v)
141
{
142
    PyInterpreterState *interp = _PyInterpreterState_GET();
143
    return sys_set_object_str(interp, name, v);
144
}
145
146
147
static int
148
should_audit(PyInterpreterState *interp)
149
{
150
    /* interp must not be NULL, but test it just in case for extra safety */
151
    assert(interp != NULL);
152
    if (!interp) {
  Branch (152:9): [True: 0, False: 4.50M]
153
        return 0;
154
    }
155
    return (interp->runtime->audit_hook_head
  Branch (155:13): [True: 1.15k, False: 4.50M]
156
            || 
interp->audit_hooks4.50M
  Branch (156:16): [True: 4.47M, False: 26.1k]
157
            || 
PyDTrace_AUDIT_ENABLED()26.1k
);
  Branch (157:16): [True: 0, False: 26.1k]
158
}
159
160
161
static int
162
sys_audit_tstate(PyThreadState *ts, const char *event,
163
                 const char *argFormat, va_list vargs)
164
{
165
    /* N format is inappropriate, because you do not know
166
       whether the reference is consumed by the call.
167
       Assert rather than exception for perf reasons */
168
    assert(!argFormat || !strchr(argFormat, 'N'));
169
170
    if (!ts) {
  Branch (170:9): [True: 154, False: 4.46M]
171
        /* Audit hooks cannot be called with a NULL thread state */
172
        return 0;
173
    }
174
175
    /* The current implementation cannot be called if tstate is not
176
       the current Python thread state. */
177
    assert(ts == _PyThreadState_GET());
178
179
    /* Early exit when no hooks are registered */
180
    PyInterpreterState *is = ts->interp;
181
    if (!should_audit(is)) {
  Branch (181:9): [True: 26.1k, False: 4.43M]
182
        return 0;
183
    }
184
185
    PyObject *eventName = NULL;
186
    PyObject *eventArgs = NULL;
187
    PyObject *hooks = NULL;
188
    PyObject *hook = NULL;
189
    int res = -1;
190
191
    int dtrace = PyDTrace_AUDIT_ENABLED();
192
193
    PyObject *exc_type, *exc_value, *exc_tb;
194
    _PyErr_Fetch(ts, &exc_type, &exc_value, &exc_tb);
195
196
    /* Initialize event args now */
197
    if (argFormat && 
argFormat[0]4.39M
) {
  Branch (197:9): [True: 4.39M, False: 44.4k]
  Branch (197:22): [True: 4.39M, False: 0]
198
        eventArgs = _Py_VaBuildValue_SizeT(argFormat, vargs);
199
        if (eventArgs && !PyTuple_Check(eventArgs)) {
  Branch (199:13): [True: 4.39M, False: 0]
  Branch (199:26): [True: 2.51M, False: 1.87M]
200
            PyObject *argTuple = PyTuple_Pack(1, eventArgs);
201
            Py_DECREF(eventArgs);
202
            eventArgs = argTuple;
203
        }
204
    }
205
    else {
206
        eventArgs = PyTuple_New(0);
207
    }
208
    if (!eventArgs) {
  Branch (208:9): [True: 0, False: 4.43M]
209
        goto exit;
210
    }
211
212
    /* Call global hooks */
213
    _Py_AuditHookEntry *e = is->runtime->audit_hook_head;
214
    for (; e; 
e = e->next1.15k
) {
  Branch (214:12): [True: 1.15k, False: 4.43M]
215
        if (e->hookCFunction(event, eventArgs, e->userData) < 0) {
  Branch (215:13): [True: 4, False: 1.15k]
216
            goto exit;
217
        }
218
    }
219
220
    /* Dtrace USDT point */
221
    if (dtrace) {
  Branch (221:9): [True: 0, False: 4.43M]
222
        PyDTrace_AUDIT(event, (void *)eventArgs);
223
    }
224
225
    /* Call interpreter hooks */
226
    if (is->audit_hooks) {
  Branch (226:9): [True: 4.43M, False: 1.15k]
227
        eventName = PyUnicode_FromString(event);
228
        if (!eventName) {
  Branch (228:13): [True: 0, False: 4.43M]
229
            goto exit;
230
        }
231
232
        hooks = PyObject_GetIter(is->audit_hooks);
233
        if (!hooks) {
  Branch (233:13): [True: 0, False: 4.43M]
234
            goto exit;
235
        }
236
237
        /* Disallow tracing in hooks unless explicitly enabled */
238
        PyThreadState_EnterTracing(ts);
239
        while ((hook = PyIter_Next(hooks)) != NULL) {
  Branch (239:16): [True: 4.43M, False: 4.43M]
240
            PyObject *o;
241
            int canTrace = _PyObject_LookupAttr(hook, &_Py_ID(__cantrace__), &o);
242
            if (o) {
  Branch (242:17): [True: 0, False: 4.43M]
243
                canTrace = PyObject_IsTrue(o);
244
                Py_DECREF(o);
245
            }
246
            if (canTrace < 0) {
  Branch (246:17): [True: 0, False: 4.43M]
247
                break;
248
            }
249
            if (canTrace) {
  Branch (249:17): [True: 0, False: 4.43M]
250
                PyThreadState_LeaveTracing(ts);
251
            }
252
            PyObject* args[2] = {eventName, eventArgs};
253
            o = _PyObject_FastCallTstate(ts, hook, args, 2);
254
            if (canTrace) {
  Branch (254:17): [True: 0, False: 4.43M]
255
                PyThreadState_EnterTracing(ts);
256
            }
257
            if (!o) {
  Branch (257:17): [True: 4, False: 4.43M]
258
                break;
259
            }
260
            Py_DECREF(o);
261
            Py_CLEAR(hook);
262
        }
263
        PyThreadState_LeaveTracing(ts);
264
        if (_PyErr_Occurred(ts)) {
  Branch (264:13): [True: 4, False: 4.43M]
265
            goto exit;
266
        }
267
    }
268
269
    res = 0;
270
271
exit:
272
    Py_XDECREF(hook);
273
    Py_XDECREF(hooks);
274
    Py_XDECREF(eventName);
275
    Py_XDECREF(eventArgs);
276
277
    if (!res) {
  Branch (277:9): [True: 4.43M, False: 8]
278
        _PyErr_Restore(ts, exc_type, exc_value, exc_tb);
279
    }
280
    else {
281
        assert(_PyErr_Occurred(ts));
282
        Py_XDECREF(exc_type);
283
        Py_XDECREF(exc_value);
284
        Py_XDECREF(exc_tb);
285
    }
286
287
    return res;
288
}
289
290
int
291
_PySys_Audit(PyThreadState *tstate, const char *event,
292
             const char *argFormat, ...)
293
{
294
    va_list vargs;
295
    va_start(vargs, argFormat);
296
    int res = sys_audit_tstate(tstate, event, argFormat, vargs);
297
    va_end(vargs);
298
    return res;
299
}
300
301
int
302
PySys_Audit(const char *event, const char *argFormat, ...)
303
{
304
    PyThreadState *tstate = _PyThreadState_GET();
305
    va_list vargs;
306
    va_start(vargs, argFormat);
307
    int res = sys_audit_tstate(tstate, event, argFormat, vargs);
308
    va_end(vargs);
309
    return res;
310
}
311
312
/* We expose this function primarily for our own cleanup during
313
 * finalization. In general, it should not need to be called,
314
 * and as such the function is not exported.
315
 *
316
 * Must be finalizing to clear hooks */
317
void
318
_PySys_ClearAuditHooks(PyThreadState *ts)
319
{
320
    assert(ts != NULL);
321
    if (!ts) {
  Branch (321:9): [True: 0, False: 103]
322
        return;
323
    }
324
325
    _PyRuntimeState *runtime = ts->interp->runtime;
326
    PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime);
327
    assert(finalizing == ts);
328
    if (finalizing != ts) {
  Branch (328:9): [True: 0, False: 103]
329
        return;
330
    }
331
332
    const PyConfig *config = _PyInterpreterState_GetConfig(ts->interp);
333
    if (config->verbose) {
  Branch (333:9): [True: 4, False: 99]
334
        PySys_WriteStderr("# clear sys.audit hooks\n");
335
    }
336
337
    /* Hooks can abort later hooks for this event, but cannot
338
       abort the clear operation itself. */
339
    _PySys_Audit(ts, "cpython._PySys_ClearAuditHooks", NULL);
340
    _PyErr_Clear(ts);
341
342
    _Py_AuditHookEntry *e = runtime->audit_hook_head, *n;
343
    runtime->audit_hook_head = NULL;
344
    while (e) {
  Branch (344:12): [True: 4, False: 103]
345
        n = e->next;
346
        PyMem_RawFree(e);
347
        e = n;
348
    }
349
}
350
351
int
352
PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
353
{
354
    /* tstate can be NULL, so access directly _PyRuntime:
355
       PySys_AddAuditHook() can be called before Python is initialized. */
356
    _PyRuntimeState *runtime = &_PyRuntime;
357
    PyThreadState *tstate;
358
    if (runtime->initialized) {
  Branch (358:9): [True: 0, False: 7]
359
        tstate = _PyRuntimeState_GetThreadState(runtime);
360
    }
361
    else {
362
        tstate = NULL;
363
    }
364
365
    /* Invoke existing audit hooks to allow them an opportunity to abort. */
366
    /* Cannot invoke hooks until we are initialized */
367
    if (tstate != NULL) {
  Branch (367:9): [True: 0, False: 7]
368
        if (_PySys_Audit(tstate, "sys.addaudithook", NULL) < 0) {
  Branch (368:13): [True: 0, False: 0]
369
            if (_PyErr_ExceptionMatches(tstate, PyExc_RuntimeError)) {
  Branch (369:17): [True: 0, False: 0]
370
                /* We do not report errors derived from RuntimeError */
371
                _PyErr_Clear(tstate);
372
                return 0;
373
            }
374
            return -1;
375
        }
376
    }
377
378
    _Py_AuditHookEntry *e = runtime->audit_hook_head;
379
    if (!e) {
  Branch (379:9): [True: 7, False: 0]
380
        e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry));
381
        runtime->audit_hook_head = e;
382
    } else {
383
        while (e->next) {
  Branch (383:16): [True: 0, False: 0]
384
            e = e->next;
385
        }
386
        e = e->next = (_Py_AuditHookEntry*)PyMem_RawMalloc(
387
            sizeof(_Py_AuditHookEntry));
388
    }
389
390
    if (!e) {
  Branch (390:9): [True: 0, False: 7]
391
        if (tstate != NULL) {
  Branch (391:13): [True: 0, False: 0]
392
            _PyErr_NoMemory(tstate);
393
        }
394
        return -1;
395
    }
396
397
    e->next = NULL;
398
    e->hookCFunction = (Py_AuditHookFunction)hook;
399
    e->userData = userData;
400
401
    return 0;
402
}
403
404
/*[clinic input]
405
sys.addaudithook
406
407
    hook: object
408
409
Adds a new audit hook callback.
410
[clinic start generated code]*/
411
412
static PyObject *
413
sys_addaudithook_impl(PyObject *module, PyObject *hook)
414
/*[clinic end generated code: output=4f9c17aaeb02f44e input=0f3e191217a45e34]*/
415
{
416
    PyThreadState *tstate = _PyThreadState_GET();
417
418
    /* Invoke existing audit hooks to allow them an opportunity to abort. */
419
    if (_PySys_Audit(tstate, "sys.addaudithook", NULL) < 0) {
  Branch (419:9): [True: 0, False: 1]
420
        if (_PyErr_ExceptionMatches(tstate, PyExc_Exception)) {
  Branch (420:13): [True: 0, False: 0]
421
            /* We do not report errors derived from Exception */
422
            _PyErr_Clear(tstate);
423
            Py_RETURN_NONE;
424
        }
425
        return NULL;
426
    }
427
428
    PyInterpreterState *interp = tstate->interp;
429
    if (interp->audit_hooks == NULL) {
  Branch (429:9): [True: 1, False: 0]
430
        interp->audit_hooks = PyList_New(0);
431
        if (interp->audit_hooks == NULL) {
  Branch (431:13): [True: 0, False: 1]
432
            return NULL;
433
        }
434
    }
435
436
    if (PyList_Append(interp->audit_hooks, hook) < 0) {
  Branch (436:9): [True: 0, False: 1]
437
        return NULL;
438
    }
439
440
    Py_RETURN_NONE;
441
}
442
443
PyDoc_STRVAR(audit_doc,
444
"audit(event, *args)\n\
445
\n\
446
Passes the event to any audit hooks that are attached.");
447
448
static PyObject *
449
sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc)
450
{
451
    PyThreadState *tstate = _PyThreadState_GET();
452
    _Py_EnsureTstateNotNULL(tstate);
453
454
    if (argc == 0) {
  Branch (454:9): [True: 0, False: 41.9k]
455
        _PyErr_SetString(tstate, PyExc_TypeError,
456
                         "audit() missing 1 required positional argument: "
457
                         "'event'");
458
        return NULL;
459
    }
460
461
    if (!should_audit(tstate->interp)) {
  Branch (461:9): [True: 0, False: 41.9k]
462
        Py_RETURN_NONE;
463
    }
464
465
    PyObject *auditEvent = args[0];
466
    if (!auditEvent) {
  Branch (466:9): [True: 0, False: 41.9k]
467
        _PyErr_SetString(tstate, PyExc_TypeError,
468
                         "expected str for argument 'event'");
469
        return NULL;
470
    }
471
    if (!PyUnicode_Check(auditEvent)) {
  Branch (471:9): [True: 0, False: 41.9k]
472
        _PyErr_Format(tstate, PyExc_TypeError,
473
                      "expected str for argument 'event', not %.200s",
474
                      Py_TYPE(auditEvent)->tp_name);
475
        return NULL;
476
    }
477
    const char *event = PyUnicode_AsUTF8(auditEvent);
478
    if (!event) {
  Branch (478:9): [True: 0, False: 41.9k]
479
        return NULL;
480
    }
481
482
    PyObject *auditArgs = _PyTuple_FromArray(args + 1, argc - 1);
483
    if (!auditArgs) {
  Branch (483:9): [True: 0, False: 41.9k]
484
        return NULL;
485
    }
486
487
    int res = _PySys_Audit(tstate, event, "O", auditArgs);
488
    Py_DECREF(auditArgs);
489
490
    if (res < 0) {
  Branch (490:9): [True: 0, False: 41.9k]
491
        return NULL;
492
    }
493
494
    Py_RETURN_NONE;
495
}
496
497
498
static PyObject *
499
sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords)
500
{
501
    PyThreadState *tstate = _PyThreadState_GET();
502
    assert(!_PyErr_Occurred(tstate));
503
    char *envar = Py_GETENV("PYTHONBREAKPOINT");
504
505
    if (envar == NULL || 
strlen(envar) == 015
) {
  Branch (505:9): [True: 2, False: 15]
  Branch (505:26): [True: 1, False: 14]
506
        envar = "pdb.set_trace";
507
    }
508
    else if (!strcmp(envar, "0")) {
  Branch (508:14): [True: 1, False: 13]
509
        /* The breakpoint is explicitly no-op'd. */
510
        Py_RETURN_NONE;
511
    }
512
    /* According to POSIX the string returned by getenv() might be invalidated
513
     * or the string content might be overwritten by a subsequent call to
514
     * getenv().  Since importing a module can performs the getenv() calls,
515
     * we need to save a copy of envar. */
516
    envar = _PyMem_RawStrdup(envar);
517
    if (envar == NULL) {
  Branch (517:9): [True: 0, False: 16]
518
        _PyErr_NoMemory(tstate);
519
        return NULL;
520
    }
521
    const char *last_dot = strrchr(envar, '.');
522
    const char *attrname = NULL;
523
    PyObject *modulepath = NULL;
524
525
    if (last_dot == NULL) {
  Branch (525:9): [True: 2, False: 14]
526
        /* The breakpoint is a built-in, e.g. PYTHONBREAKPOINT=int */
527
        modulepath = PyUnicode_FromString("builtins");
528
        attrname = envar;
529
    }
530
    else if (last_dot != envar) {
  Branch (530:14): [True: 11, False: 3]
531
        /* Split on the last dot; */
532
        modulepath = PyUnicode_FromStringAndSize(envar, last_dot - envar);
533
        attrname = last_dot + 1;
534
    }
535
    else {
536
        goto warn;
537
    }
538
    if (modulepath == NULL) {
  Branch (538:9): [True: 0, False: 13]
539
        PyMem_RawFree(envar);
540
        return NULL;
541
    }
542
543
    PyObject *module = PyImport_Import(modulepath);
544
    Py_DECREF(modulepath);
545
546
    if (module == NULL) {
  Branch (546:9): [True: 7, False: 6]
547
        if (_PyErr_ExceptionMatches(tstate, PyExc_ImportError)) {
  Branch (547:13): [True: 7, False: 0]
548
            goto warn;
549
        }
550
        PyMem_RawFree(envar);
551
        return NULL;
552
    }
553
554
    PyObject *hook = PyObject_GetAttrString(module, attrname);
555
    Py_DECREF(module);
556
557
    if (hook == NULL) {
  Branch (557:9): [True: 1, False: 5]
558
        if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
  Branch (558:13): [True: 1, False: 0]
559
            goto warn;
560
        }
561
        PyMem_RawFree(envar);
562
        return NULL;
563
    }
564
    PyMem_RawFree(envar);
565
    PyObject *retval = PyObject_Vectorcall(hook, args, nargs, keywords);
566
    Py_DECREF(hook);
567
    return retval;
568
569
  warn:
570
    /* If any of the imports went wrong, then warn and ignore. */
571
    _PyErr_Clear(tstate);
572
    int status = PyErr_WarnFormat(
573
        PyExc_RuntimeWarning, 0,
574
        "Ignoring unimportable $PYTHONBREAKPOINT: \"%s\"", envar);
575
    PyMem_RawFree(envar);
576
    if (status < 0) {
  Branch (576:9): [True: 0, False: 11]
577
        /* Printing the warning raised an exception. */
578
        return NULL;
579
    }
580
    /* The warning was (probably) issued. */
581
    Py_RETURN_NONE;
582
}
583
584
PyDoc_STRVAR(breakpointhook_doc,
585
"breakpointhook(*args, **kws)\n"
586
"\n"
587
"This hook function is called by built-in breakpoint().\n"
588
);
589
590
/* Write repr(o) to sys.stdout using sys.stdout.encoding and 'backslashreplace'
591
   error handler. If sys.stdout has a buffer attribute, use
592
   sys.stdout.buffer.write(encoded), otherwise redecode the string and use
593
   sys.stdout.write(redecoded).
594
595
   Helper function for sys_displayhook(). */
596
static int
597
sys_displayhook_unencodable(PyObject *outf, PyObject *o)
598
{
599
    PyObject *stdout_encoding = NULL;
600
    PyObject *encoded, *escaped_str, *repr_str, *buffer, *result;
601
    const char *stdout_encoding_str;
602
    int ret;
603
604
    stdout_encoding = PyObject_GetAttr(outf, &_Py_ID(encoding));
605
    if (stdout_encoding == NULL)
  Branch (605:9): [True: 0, False: 0]
606
        goto error;
607
    stdout_encoding_str = PyUnicode_AsUTF8(stdout_encoding);
608
    if (stdout_encoding_str == NULL)
  Branch (608:9): [True: 0, False: 0]
609
        goto error;
610
611
    repr_str = PyObject_Repr(o);
612
    if (repr_str == NULL)
  Branch (612:9): [True: 0, False: 0]
613
        goto error;
614
    encoded = PyUnicode_AsEncodedString(repr_str,
615
                                        stdout_encoding_str,
616
                                        "backslashreplace");
617
    Py_DECREF(repr_str);
618
    if (encoded == NULL)
  Branch (618:9): [True: 0, False: 0]
619
        goto error;
620
621
    if (_PyObject_LookupAttr(outf, &_Py_ID(buffer), &buffer) < 0) {
  Branch (621:9): [True: 0, False: 0]
622
        Py_DECREF(encoded);
623
        goto error;
624
    }
625
    if (buffer) {
  Branch (625:9): [True: 0, False: 0]
626
        result = PyObject_CallMethodOneArg(buffer, &_Py_ID(write), encoded);
627
        Py_DECREF(buffer);
628
        Py_DECREF(encoded);
629
        if (result == NULL)
  Branch (629:13): [True: 0, False: 0]
630
            goto error;
631
        Py_DECREF(result);
632
    }
633
    else {
634
        escaped_str = PyUnicode_FromEncodedObject(encoded,
635
                                                  stdout_encoding_str,
636
                                                  "strict");
637
        Py_DECREF(encoded);
638
        if (PyFile_WriteObject(escaped_str, outf, Py_PRINT_RAW) != 0) {
  Branch (638:13): [True: 0, False: 0]
639
            Py_DECREF(escaped_str);
640
            goto error;
641
        }
642
        Py_DECREF(escaped_str);
643
    }
644
    ret = 0;
645
    goto finally;
646
647
error:
648
    ret = -1;
649
finally:
650
    Py_XDECREF(stdout_encoding);
651
    return ret;
652
}
653
654
/*[clinic input]
655
sys.displayhook
656
657
    object as o: object
658
    /
659
660
Print an object to sys.stdout and also save it in builtins._
661
[clinic start generated code]*/
662
663
static PyObject *
664
sys_displayhook(PyObject *module, PyObject *o)
665
/*[clinic end generated code: output=347477d006df92ed input=08ba730166d7ef72]*/
666
{
667
    PyObject *outf;
668
    PyObject *builtins;
669
    PyThreadState *tstate = _PyThreadState_GET();
670
671
    builtins = PyImport_GetModule(&_Py_ID(builtins));
672
    if (builtins == NULL) {
  Branch (672:9): [True: 0, False: 3.01k]
673
        if (!_PyErr_Occurred(tstate)) {
  Branch (673:13): [True: 0, False: 0]
674
            _PyErr_SetString(tstate, PyExc_RuntimeError,
675
                             "lost builtins module");
676
        }
677
        return NULL;
678
    }
679
    Py_DECREF(builtins);
680
681
    /* Print value except if None */
682
    /* After printing, also assign to '_' */
683
    /* Before, set '_' to None to avoid recursion */
684
    if (o == Py_None) {
  Branch (684:9): [True: 1.41k, False: 1.60k]
685
        Py_RETURN_NONE;
686
    }
687
    if (PyObject_SetAttr(builtins, &_Py_ID(_), Py_None) != 0)
  Branch (687:9): [True: 0, False: 1.60k]
688
        return NULL;
689
    outf = _PySys_GetAttr(tstate, &_Py_ID(stdout));
690
    if (outf == NULL || 
outf == 1.60k
Py_None1.60k
) {
  Branch (690:9): [True: 1, False: 1.60k]
  Branch (690:25): [True: 0, False: 1.60k]
691
        _PyErr_SetString(tstate, PyExc_RuntimeError, "lost sys.stdout");
692
        return NULL;
693
    }
694
    if (PyFile_WriteObject(o, outf, 0) != 0) {
  Branch (694:9): [True: 0, False: 1.60k]
695
        if (_PyErr_ExceptionMatches(tstate, PyExc_UnicodeEncodeError)) {
  Branch (695:13): [True: 0, False: 0]
696
            int err;
697
            /* repr(o) is not encodable to sys.stdout.encoding with
698
             * sys.stdout.errors error handler (which is probably 'strict') */
699
            _PyErr_Clear(tstate);
700
            err = sys_displayhook_unencodable(outf, o);
701
            if (err) {
  Branch (701:17): [True: 0, False: 0]
702
                return NULL;
703
            }
704
        }
705
        else {
706
            return NULL;
707
        }
708
    }
709
    _Py_DECLARE_STR(newline, "\n");
710
    if (PyFile_WriteObject(&_Py_STR(newline), outf, Py_PRINT_RAW) != 0)
  Branch (710:9): [True: 0, False: 1.60k]
711
        return NULL;
712
    if (PyObject_SetAttr(builtins, &_Py_ID(_), o) != 0)
  Branch (712:9): [True: 0, False: 1.60k]
713
        return NULL;
714
    Py_RETURN_NONE;
715
}
716
717
718
/*[clinic input]
719
sys.excepthook
720
721
    exctype:   object
722
    value:     object
723
    traceback: object
724
    /
725
726
Handle an exception by displaying it with a traceback on sys.stderr.
727
[clinic start generated code]*/
728
729
static PyObject *
730
sys_excepthook_impl(PyObject *module, PyObject *exctype, PyObject *value,
731
                    PyObject *traceback)
732
/*[clinic end generated code: output=18d99fdda21b6b5e input=ecf606fa826f19d9]*/
733
{
734
    PyErr_Display(exctype, value, traceback);
735
    Py_RETURN_NONE;
736
}
737
738
739
/*[clinic input]
740
sys.exception
741
742
Return the current exception.
743
744
Return the most recent exception caught by an except clause
745
in the current stack frame or in an older stack frame, or None
746
if no such exception exists.
747
[clinic start generated code]*/
748
749
static PyObject *
750
sys_exception_impl(PyObject *module)
751
/*[clinic end generated code: output=2381ee2f25953e40 input=c88fbb94b6287431]*/
752
{
753
    _PyErr_StackItem *err_info = _PyErr_GetTopmostException(_PyThreadState_GET());
754
    if (err_info->exc_value != NULL) {
  Branch (754:9): [True: 6, False: 0]
755
        return Py_NewRef(err_info->exc_value);
756
    }
757
    
Py_RETURN_NONE0
;
758
}
759
760
761
/*[clinic input]
762
sys.exc_info
763
764
Return current exception information: (type, value, traceback).
765
766
Return information about the most recent exception caught by an except
767
clause in the current stack frame or in an older stack frame.
768
[clinic start generated code]*/
769
770
static PyObject *
771
sys_exc_info_impl(PyObject *module)
772
/*[clinic end generated code: output=3afd0940cf3a4d30 input=b5c5bf077788a3e5]*/
773
{
774
    _PyErr_StackItem *err_info = _PyErr_GetTopmostException(_PyThreadState_GET());
775
    return _PyErr_StackItemToExcInfoTuple(err_info);
776
}
777
778
779
/*[clinic input]
780
sys.unraisablehook
781
782
    unraisable: object
783
    /
784
785
Handle an unraisable exception.
786
787
The unraisable argument has the following attributes:
788
789
* exc_type: Exception type.
790
* exc_value: Exception value, can be None.
791
* exc_traceback: Exception traceback, can be None.
792
* err_msg: Error message, can be None.
793
* object: Object causing the exception, can be None.
794
[clinic start generated code]*/
795
796
static PyObject *
797
sys_unraisablehook(PyObject *module, PyObject *unraisable)
798
/*[clinic end generated code: output=bb92838b32abaa14 input=ec3af148294af8d3]*/
799
{
800
    return _PyErr_WriteUnraisableDefaultHook(unraisable);
801
}
802
803
804
/*[clinic input]
805
sys.exit
806
807
    status: object = None
808
    /
809
810
Exit the interpreter by raising SystemExit(status).
811
812
If the status is omitted or None, it defaults to zero (i.e., success).
813
If the status is an integer, it will be used as the system exit status.
814
If it is another kind of object, it will be printed and the system
815
exit status will be one (i.e., failure).
816
[clinic start generated code]*/
817
818
static PyObject *
819
sys_exit_impl(PyObject *module, PyObject *status)
820
/*[clinic end generated code: output=13870986c1ab2ec0 input=b86ca9497baa94f2]*/
821
{
822
    /* Raise SystemExit so callers may catch it or clean up. */
823
    PyErr_SetObject(PyExc_SystemExit, status);
824
    return NULL;
825
}
826
827
828
829
/*[clinic input]
830
sys.getdefaultencoding
831
832
Return the current default encoding used by the Unicode implementation.
833
[clinic start generated code]*/
834
835
static PyObject *
836
sys_getdefaultencoding_impl(PyObject *module)
837
/*[clinic end generated code: output=256d19dfcc0711e6 input=d416856ddbef6909]*/
838
{
839
    _Py_DECLARE_STR(utf_8, "utf-8");
840
    PyObject *ret = &_Py_STR(utf_8);
841
    Py_INCREF(ret);
842
    return ret;
843
}
844
845
/*[clinic input]
846
sys.getfilesystemencoding
847
848
Return the encoding used to convert Unicode filenames to OS filenames.
849
[clinic start generated code]*/
850
851
static PyObject *
852
sys_getfilesystemencoding_impl(PyObject *module)
853
/*[clinic end generated code: output=1dc4bdbe9be44aa7 input=8475f8649b8c7d8c]*/
854
{
855
    PyInterpreterState *interp = _PyInterpreterState_GET();
856
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);
857
    return PyUnicode_FromWideChar(config->filesystem_encoding, -1);
858
}
859
860
/*[clinic input]
861
sys.getfilesystemencodeerrors
862
863
Return the error mode used Unicode to OS filename conversion.
864
[clinic start generated code]*/
865
866
static PyObject *
867
sys_getfilesystemencodeerrors_impl(PyObject *module)
868
/*[clinic end generated code: output=ba77b36bbf7c96f5 input=22a1e8365566f1e5]*/
869
{
870
    PyInterpreterState *interp = _PyInterpreterState_GET();
871
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);
872
    return PyUnicode_FromWideChar(config->filesystem_errors, -1);
873
}
874
875
/*[clinic input]
876
sys.intern
877
878
    string as s: unicode
879
    /
880
881
``Intern'' the given string.
882
883
This enters the string in the (global) table of interned strings whose
884
purpose is to speed up dictionary lookups. Return the string itself or
885
the previously interned string object with the same value.
886
[clinic start generated code]*/
887
888
static PyObject *
889
sys_intern_impl(PyObject *module, PyObject *s)
890
/*[clinic end generated code: output=be680c24f5c9e5d6 input=849483c006924e2f]*/
891
{
892
    if (PyUnicode_CheckExact(s)) {
893
        Py_INCREF(s);
894
        PyUnicode_InternInPlace(&s);
895
        return s;
896
    }
897
    else {
898
        PyErr_Format(PyExc_TypeError,
899
                     "can't intern %.400s", Py_TYPE(s)->tp_name);
900
        return NULL;
901
    }
902
}
903
904
905
/*
906
 * Cached interned string objects used for calling the profile and
907
 * trace functions.
908
 */
909
static PyObject *whatstrings[8] = {
910
   &_Py_ID(call),
911
   &_Py_ID(exception),
912
   &_Py_ID(line),
913
   &_Py_ID(return),
914
   &_Py_ID(c_call),
915
   &_Py_ID(c_exception),
916
   &_Py_ID(c_return),
917
   &_Py_ID(opcode),
918
};
919
920
921
static PyObject *
922
call_trampoline(PyThreadState *tstate, PyObject* callback,
923
                PyFrameObject *frame, int what, PyObject *arg)
924
{
925
926
    PyObject *stack[3];
927
    stack[0] = (PyObject *)frame;
928
    stack[1] = whatstrings[what];
929
    stack[2] = (arg != NULL) ? 
arg888k
:
Py_None393
;
  Branch (929:16): [True: 888k, False: 393]
930
931
    /* Discard any previous modifications the frame's fast locals */
932
    if (frame->f_fast_as_locals) {
  Branch (932:9): [True: 41, False: 889k]
933
        if (PyFrame_FastToLocalsWithError(frame) < 0) {
  Branch (933:13): [True: 0, False: 41]
934
            return NULL;
935
        }
936
    }
937
938
    /* call the Python-level function */
939
    PyObject *result = _PyObject_FastCallTstate(tstate, callback, stack, 3);
940
941
    PyFrame_LocalsToFast(frame, 1);
942
    if (result == NULL) {
  Branch (942:9): [True: 4.07k, False: 885k]
943
        PyTraceBack_Here(frame);
944
    }
945
946
    return result;
947
}
948
949
static int
950
profile_trampoline(PyObject *self, PyFrameObject *frame,
951
                   int what, PyObject *arg)
952
{
953
    if (arg == NULL) {
  Branch (953:9): [True: 192, False: 1.64k]
954
        arg = Py_None;
955
    }
956
957
    PyThreadState *tstate = _PyThreadState_GET();
958
    PyObject *result = call_trampoline(tstate, self, frame, what, arg);
959
    if (result == NULL) {
  Branch (959:9): [True: 0, False: 1.83k]
960
        _PyEval_SetProfile(tstate, NULL, NULL);
961
        return -1;
962
    }
963
964
    Py_DECREF(result);
965
    return 0;
966
}
967
968
static int
969
trace_trampoline(PyObject *self, PyFrameObject *frame,
970
                 int what, PyObject *arg)
971
{
972
    PyObject *callback;
973
    if (what == PyTrace_CALL) {
  Branch (973:9): [True: 135k, False: 1.41M]
974
        callback = self;
975
    }
976
    else {
977
        callback = frame->f_trace;
978
    }
979
    if (callback == NULL) {
  Branch (979:9): [True: 661k, False: 887k]
980
        return 0;
981
    }
982
983
    PyThreadState *tstate = _PyThreadState_GET();
984
    PyObject *result = call_trampoline(tstate, callback, frame, what, arg);
985
    if (result == NULL) {
  Branch (985:9): [True: 4.07k, False: 883k]
986
        _PyEval_SetTrace(tstate, NULL, NULL);
987
        Py_CLEAR(frame->f_trace);
988
        return -1;
989
    }
990
991
    if (result != Py_None) {
  Branch (991:9): [True: 824k, False: 58.7k]
992
        Py_XSETREF(frame->f_trace, result);
993
    }
994
    else {
995
        Py_DECREF(result);
996
    }
997
    return 0;
998
}
999
1000
static PyObject *
1001
sys_settrace(PyObject *self, PyObject *args)
1002
{
1003
    PyThreadState *tstate = _PyThreadState_GET();
1004
    if (args == Py_None) {
  Branch (1004:9): [True: 2.05k, False: 4.96k]
1005
        if (_PyEval_SetTrace(tstate, NULL, NULL) < 0) {
  Branch (1005:13): [True: 0, False: 2.05k]
1006
            return NULL;
1007
        }
1008
    }
1009
    else {
1010
        if (_PyEval_SetTrace(tstate, trace_trampoline, args) < 0) {
  Branch (1010:13): [True: 1, False: 4.96k]
1011
            return NULL;
1012
        }
1013
    }
1014
    
Py_RETURN_NONE7.02k
;
1015
}
1016
1017
PyDoc_STRVAR(settrace_doc,
1018
"settrace(function)\n\
1019
\n\
1020
Set the global debug tracing function.  It will be called on each\n\
1021
function call.  See the debugger chapter in the library manual."
1022
);
1023
1024
/*[clinic input]
1025
sys.gettrace
1026
1027
Return the global debug tracing function set with sys.settrace.
1028
1029
See the debugger chapter in the library manual.
1030
[clinic start generated code]*/
1031
1032
static PyObject *
1033
sys_gettrace_impl(PyObject *module)
1034
/*[clinic end generated code: output=e97e3a4d8c971b6e input=373b51bb2147f4d8]*/
1035
{
1036
    PyThreadState *tstate = _PyThreadState_GET();
1037
    PyObject *temp = tstate->c_traceobj;
1038
1039
    if (temp == NULL)
  Branch (1039:9): [True: 3.25k, False: 5]
1040
        temp = Py_None;
1041
    Py_INCREF(temp);
1042
    return temp;
1043
}
1044
1045
static PyObject *
1046
sys_setprofile(PyObject *self, PyObject *args)
1047
{
1048
    PyThreadState *tstate = _PyThreadState_GET();
1049
    if (args == Py_None) {
  Branch (1049:9): [True: 52, False: 50]
1050
        if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) {
  Branch (1050:13): [True: 0, False: 52]
1051
            return NULL;
1052
        }
1053
    }
1054
    else {
1055
        if (_PyEval_SetProfile(tstate, profile_trampoline, args) < 0) {
  Branch (1055:13): [True: 1, False: 49]
1056
            return NULL;
1057
        }
1058
    }
1059
    
Py_RETURN_NONE101
;
1060
}
1061
1062
PyDoc_STRVAR(setprofile_doc,
1063
"setprofile(function)\n\
1064
\n\
1065
Set the profiling function.  It will be called on each function call\n\
1066
and return.  See the profiler chapter in the library manual."
1067
);
1068
1069
/*[clinic input]
1070
sys.getprofile
1071
1072
Return the profiling function set with sys.setprofile.
1073
1074
See the profiler chapter in the library manual.
1075
[clinic start generated code]*/
1076
1077
static PyObject *
1078
sys_getprofile_impl(PyObject *module)
1079
/*[clinic end generated code: output=579b96b373448188 input=1b3209d89a32965d]*/
1080
{
1081
    PyThreadState *tstate = _PyThreadState_GET();
1082
    PyObject *temp = tstate->c_profileobj;
1083
1084
    if (temp == NULL)
  Branch (1084:9): [True: 5, False: 5]
1085
        temp = Py_None;
1086
    Py_INCREF(temp);
1087
    return temp;
1088
}
1089
1090
1091
/*[clinic input]
1092
sys.setswitchinterval
1093
1094
    interval: double
1095
    /
1096
1097
Set the ideal thread switching delay inside the Python interpreter.
1098
1099
The actual frequency of switching threads can be lower if the
1100
interpreter executes long sequences of uninterruptible code
1101
(this is implementation-specific and workload-dependent).
1102
1103
The parameter must represent the desired switching delay in seconds
1104
A typical value is 0.005 (5 milliseconds).
1105
[clinic start generated code]*/
1106
1107
static PyObject *
1108
sys_setswitchinterval_impl(PyObject *module, double interval)
1109
/*[clinic end generated code: output=65a19629e5153983 input=561b477134df91d9]*/
1110
{
1111
    if (interval <= 0.0) {
  Branch (1111:9): [True: 2, False: 133]
1112
        PyErr_SetString(PyExc_ValueError,
1113
                        "switch interval must be strictly positive");
1114
        return NULL;
1115
    }
1116
    _PyEval_SetSwitchInterval((unsigned long) (1e6 * interval));
1117
    Py_RETURN_NONE;
1118
}
1119
1120
1121
/*[clinic input]
1122
sys.getswitchinterval -> double
1123
1124
Return the current thread switch interval; see sys.setswitchinterval().
1125
[clinic start generated code]*/
1126
1127
static double
1128
sys_getswitchinterval_impl(PyObject *module)
1129
/*[clinic end generated code: output=a38c277c85b5096d input=bdf9d39c0ebbbb6f]*/
1130
{
1131
    return 1e-6 * _PyEval_GetSwitchInterval();
1132
}
1133
1134
/*[clinic input]
1135
sys.setrecursionlimit
1136
1137
    limit as new_limit: int
1138
    /
1139
1140
Set the maximum depth of the Python interpreter stack to n.
1141
1142
This limit prevents infinite recursion from causing an overflow of the C
1143
stack and crashing Python.  The highest possible limit is platform-
1144
dependent.
1145
[clinic start generated code]*/
1146
1147
static PyObject *
1148
sys_setrecursionlimit_impl(PyObject *module, int new_limit)
1149
/*[clinic end generated code: output=35e1c64754800ace input=b0f7a23393924af3]*/
1150
{
1151
    PyThreadState *tstate = _PyThreadState_GET();
1152
1153
    if (new_limit < 1) {
  Branch (1153:9): [True: 1, False: 131]
1154
        _PyErr_SetString(tstate, PyExc_ValueError,
1155
                         "recursion limit must be greater or equal than 1");
1156
        return NULL;
1157
    }
1158
1159
    /* Reject too low new limit if the current recursion depth is higher than
1160
       the new low-water mark. */
1161
    int depth = tstate->recursion_limit - tstate->recursion_remaining;
1162
    if (depth >= new_limit) {
  Branch (1162:9): [True: 40, False: 91]
1163
        _PyErr_Format(tstate, PyExc_RecursionError,
1164
                      "cannot set the recursion limit to %i at "
1165
                      "the recursion depth %i: the limit is too low",
1166
                      new_limit, depth);
1167
        return NULL;
1168
    }
1169
1170
    Py_SetRecursionLimit(new_limit);
1171
    Py_RETURN_NONE;
1172
}
1173
1174
/*[clinic input]
1175
sys.set_coroutine_origin_tracking_depth
1176
1177
  depth: int
1178
1179
Enable or disable origin tracking for coroutine objects in this thread.
1180
1181
Coroutine objects will track 'depth' frames of traceback information
1182
about where they came from, available in their cr_origin attribute.
1183
1184
Set a depth of 0 to disable.
1185
[clinic start generated code]*/
1186
1187
static PyObject *
1188
sys_set_coroutine_origin_tracking_depth_impl(PyObject *module, int depth)
1189
/*[clinic end generated code: output=0a2123c1cc6759c5 input=a1d0a05f89d2c426]*/
1190
{
1191
    if (_PyEval_SetCoroutineOriginTrackingDepth(depth) < 0) {
  Branch (1191:9): [True: 1, False: 2.45k]
1192
        return NULL;
1193
    }
1194
    
Py_RETURN_NONE2.45k
;
1195
}
1196
1197
/*[clinic input]
1198
sys.get_coroutine_origin_tracking_depth -> int
1199
1200
Check status of origin tracking for coroutine objects in this thread.
1201
[clinic start generated code]*/
1202
1203
static int
1204
sys_get_coroutine_origin_tracking_depth_impl(PyObject *module)
1205
/*[clinic end generated code: output=3699f7be95a3afb8 input=335266a71205b61a]*/
1206
{
1207
    return _PyEval_GetCoroutineOriginTrackingDepth();
1208
}
1209
1210
static PyTypeObject AsyncGenHooksType;
1211
1212
PyDoc_STRVAR(asyncgen_hooks_doc,
1213
"asyncgen_hooks\n\
1214
\n\
1215
A named tuple providing information about asynchronous\n\
1216
generators hooks.  The attributes are read only.");
1217
1218
static PyStructSequence_Field asyncgen_hooks_fields[] = {
1219
    {"firstiter", "Hook to intercept first iteration"},
1220
    {"finalizer", "Hook to intercept finalization"},
1221
    {0}
1222
};
1223
1224
static PyStructSequence_Desc asyncgen_hooks_desc = {
1225
    "asyncgen_hooks",          /* name */
1226
    asyncgen_hooks_doc,        /* doc */
1227
    asyncgen_hooks_fields ,    /* fields */
1228
    2
1229
};
1230
1231
static PyObject *
1232
sys_set_asyncgen_hooks(PyObject *self, PyObject *args, PyObject *kw)
1233
{
1234
    static char *keywords[] = {"firstiter", "finalizer", NULL};
1235
    PyObject *firstiter = NULL;
1236
    PyObject *finalizer = NULL;
1237
1238
    if (!PyArg_ParseTupleAndKeywords(
  Branch (1238:9): [True: 0, False: 10.3k]
1239
            args, kw, "|OO", keywords,
1240
            &firstiter, &finalizer)) {
1241
        return NULL;
1242
    }
1243
1244
    if (finalizer && 
finalizer != 10.3k
Py_None10.3k
) {
  Branch (1244:9): [True: 10.3k, False: 1]
  Branch (1244:22): [True: 5.15k, False: 5.15k]
1245
        if (!PyCallable_Check(finalizer)) {
  Branch (1245:13): [True: 0, False: 5.15k]
1246
            PyErr_Format(PyExc_TypeError,
1247
                         "callable finalizer expected, got %.50s",
1248
                         Py_TYPE(finalizer)->tp_name);
1249
            return NULL;
1250
        }
1251
        if (_PyEval_SetAsyncGenFinalizer(finalizer) < 0) {
  Branch (1251:13): [True: 0, False: 5.15k]
1252
            return NULL;
1253
        }
1254
    }
1255
    else if (finalizer == Py_None && 
_PyEval_SetAsyncGenFinalizer(NULL) < 05.15k
) {
  Branch (1255:14): [True: 5.15k, False: 1]
  Branch (1255:38): [True: 0, False: 5.15k]
1256
        return NULL;
1257
    }
1258
1259
    if (firstiter && 
firstiter != 10.3k
Py_None10.3k
) {
  Branch (1259:9): [True: 10.3k, False: 1]
  Branch (1259:22): [True: 5.15k, False: 5.15k]
1260
        if (!PyCallable_Check(firstiter)) {
  Branch (1260:13): [True: 0, False: 5.15k]
1261
            PyErr_Format(PyExc_TypeError,
1262
                         "callable firstiter expected, got %.50s",
1263
                         Py_TYPE(firstiter)->tp_name);
1264
            return NULL;
1265
        }
1266
        if (_PyEval_SetAsyncGenFirstiter(firstiter) < 0) {
  Branch (1266:13): [True: 0, False: 5.15k]
1267
            return NULL;
1268
        }
1269
    }
1270
    else if (firstiter == Py_None && 
_PyEval_SetAsyncGenFirstiter(NULL) < 05.15k
) {
  Branch (1270:14): [True: 5.15k, False: 1]
  Branch (1270:38): [True: 0, False: 5.15k]
1271
        return NULL;
1272
    }
1273
1274
    Py_RETURN_NONE;
1275
}
1276
1277
PyDoc_STRVAR(set_asyncgen_hooks_doc,
1278
"set_asyncgen_hooks(* [, firstiter] [, finalizer])\n\
1279
\n\
1280
Set a finalizer for async generators objects."
1281
);
1282
1283
/*[clinic input]
1284
sys.get_asyncgen_hooks
1285
1286
Return the installed asynchronous generators hooks.
1287
1288
This returns a namedtuple of the form (firstiter, finalizer).
1289
[clinic start generated code]*/
1290
1291
static PyObject *
1292
sys_get_asyncgen_hooks_impl(PyObject *module)
1293
/*[clinic end generated code: output=53a253707146f6cf input=3676b9ea62b14625]*/
1294
{
1295
    PyObject *res;
1296
    PyObject *firstiter = _PyEval_GetAsyncGenFirstiter();
1297
    PyObject *finalizer = _PyEval_GetAsyncGenFinalizer();
1298
1299
    res = PyStructSequence_New(&AsyncGenHooksType);
1300
    if (res == NULL) {
  Branch (1300:9): [True: 0, False: 5.16k]
1301
        return NULL;
1302
    }
1303
1304
    if (firstiter == NULL) {
  Branch (1304:9): [True: 5.15k, False: 2]
1305
        firstiter = Py_None;
1306
    }
1307
1308
    if (finalizer == NULL) {
  Branch (1308:9): [True: 5.15k, False: 1]
1309
        finalizer = Py_None;
1310
    }
1311
1312
    Py_INCREF(firstiter);
1313
    PyStructSequence_SET_ITEM(res, 0, firstiter);
1314
1315
    Py_INCREF(finalizer);
1316
    PyStructSequence_SET_ITEM(res, 1, finalizer);
1317
1318
    return res;
1319
}
1320
1321
1322
static PyTypeObject Hash_InfoType;
1323
1324
PyDoc_STRVAR(hash_info_doc,
1325
"hash_info\n\
1326
\n\
1327
A named tuple providing parameters used for computing\n\
1328
hashes. The attributes are read only.");
1329
1330
static PyStructSequence_Field hash_info_fields[] = {
1331
    {"width", "width of the type used for hashing, in bits"},
1332
    {"modulus", "prime number giving the modulus on which the hash "
1333
                "function is based"},
1334
    {"inf", "value to be used for hash of a positive infinity"},
1335
    {"nan", "value to be used for hash of a nan"},
1336
    {"imag", "multiplier used for the imaginary part of a complex number"},
1337
    {"algorithm", "name of the algorithm for hashing of str, bytes and "
1338
                  "memoryviews"},
1339
    {"hash_bits", "internal output size of hash algorithm"},
1340
    {"seed_bits", "seed size of hash algorithm"},
1341
    {"cutoff", "small string optimization cutoff"},
1342
    {NULL, NULL}
1343
};
1344
1345
static PyStructSequence_Desc hash_info_desc = {
1346
    "sys.hash_info",
1347
    hash_info_doc,
1348
    hash_info_fields,
1349
    9,
1350
};
1351
1352
static PyObject *
1353
get_hash_info(PyThreadState *tstate)
1354
{
1355
    PyObject *hash_info;
1356
    int field = 0;
1357
    PyHash_FuncDef *hashfunc;
1358
    hash_info = PyStructSequence_New(&Hash_InfoType);
1359
    if (hash_info == NULL)
  Branch (1359:9): [True: 0, False: 278]
1360
        return NULL;
1361
    hashfunc = PyHash_GetFuncDef();
1362
    PyStructSequence_SET_ITEM(hash_info, field++,
1363
                              PyLong_FromLong(8*sizeof(Py_hash_t)));
1364
    PyStructSequence_SET_ITEM(hash_info, field++,
1365
                              PyLong_FromSsize_t(_PyHASH_MODULUS));
1366
    PyStructSequence_SET_ITEM(hash_info, field++,
1367
                              PyLong_FromLong(_PyHASH_INF));
1368
    PyStructSequence_SET_ITEM(hash_info, field++,
1369
                              PyLong_FromLong(0));  // This is no longer used
1370
    PyStructSequence_SET_ITEM(hash_info, field++,
1371
                              PyLong_FromLong(_PyHASH_IMAG));
1372
    PyStructSequence_SET_ITEM(hash_info, field++,
1373
                              PyUnicode_FromString(hashfunc->name));
1374
    PyStructSequence_SET_ITEM(hash_info, field++,
1375
                              PyLong_FromLong(hashfunc->hash_bits));
1376
    PyStructSequence_SET_ITEM(hash_info, field++,
1377
                              PyLong_FromLong(hashfunc->seed_bits));
1378
    PyStructSequence_SET_ITEM(hash_info, field++,
1379
                              PyLong_FromLong(Py_HASH_CUTOFF));
1380
    if (_PyErr_Occurred(tstate)) {
  Branch (1380:9): [True: 0, False: 278]
1381
        Py_CLEAR(hash_info);
1382
        return NULL;
1383
    }
1384
    return hash_info;
1385
}
1386
/*[clinic input]
1387
sys.getrecursionlimit
1388
1389
Return the current value of the recursion limit.
1390
1391
The recursion limit is the maximum depth of the Python interpreter
1392
stack.  This limit prevents infinite recursion from causing an overflow
1393
of the C stack and crashing Python.
1394
[clinic start generated code]*/
1395
1396
static PyObject *
1397
sys_getrecursionlimit_impl(PyObject *module)
1398
/*[clinic end generated code: output=d571fb6b4549ef2e input=1c6129fd2efaeea8]*/
1399
{
1400
    return PyLong_FromLong(Py_GetRecursionLimit());
1401
}
1402
1403
#ifdef MS_WINDOWS
1404
1405
static PyTypeObject WindowsVersionType = {0, 0, 0, 0, 0, 0};
1406
1407
static PyStructSequence_Field windows_version_fields[] = {
1408
    {"major", "Major version number"},
1409
    {"minor", "Minor version number"},
1410
    {"build", "Build number"},
1411
    {"platform", "Operating system platform"},
1412
    {"service_pack", "Latest Service Pack installed on the system"},
1413
    {"service_pack_major", "Service Pack major version number"},
1414
    {"service_pack_minor", "Service Pack minor version number"},
1415
    {"suite_mask", "Bit mask identifying available product suites"},
1416
    {"product_type", "System product type"},
1417
    {"platform_version", "Diagnostic version number"},
1418
    {0}
1419
};
1420
1421
static PyStructSequence_Desc windows_version_desc = {
1422
    "sys.getwindowsversion",       /* name */
1423
    sys_getwindowsversion__doc__,  /* doc */
1424
    windows_version_fields,        /* fields */
1425
    5                              /* For backward compatibility,
1426
                                      only the first 5 items are accessible
1427
                                      via indexing, the rest are name only */
1428
};
1429
1430
/* Disable deprecation warnings about GetVersionEx as the result is
1431
   being passed straight through to the caller, who is responsible for
1432
   using it correctly. */
1433
#pragma warning(push)
1434
#pragma warning(disable:4996)
1435
1436
/*[clinic input]
1437
sys.getwindowsversion
1438
1439
Return info about the running version of Windows as a named tuple.
1440
1441
The members are named: major, minor, build, platform, service_pack,
1442
service_pack_major, service_pack_minor, suite_mask, product_type and
1443
platform_version. For backward compatibility, only the first 5 items
1444
are available by indexing. All elements are numbers, except
1445
service_pack and platform_type which are strings, and platform_version
1446
which is a 3-tuple. Platform is always 2. Product_type may be 1 for a
1447
workstation, 2 for a domain controller, 3 for a server.
1448
Platform_version is a 3-tuple containing a version number that is
1449
intended for identifying the OS rather than feature detection.
1450
[clinic start generated code]*/
1451
1452
static PyObject *
1453
sys_getwindowsversion_impl(PyObject *module)
1454
/*[clinic end generated code: output=1ec063280b932857 input=73a228a328fee63a]*/
1455
{
1456
    PyObject *version;
1457
    int pos = 0;
1458
    OSVERSIONINFOEXW ver;
1459
    DWORD realMajor, realMinor, realBuild;
1460
    HANDLE hKernel32;
1461
    wchar_t kernel32_path[MAX_PATH];
1462
    LPVOID verblock;
1463
    DWORD verblock_size;
1464
1465
    ver.dwOSVersionInfoSize = sizeof(ver);
1466
    if (!GetVersionExW((OSVERSIONINFOW*) &ver))
1467
        return PyErr_SetFromWindowsErr(0);
1468
1469
    version = PyStructSequence_New(&WindowsVersionType);
1470
    if (version == NULL)
1471
        return NULL;
1472
1473
    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMajorVersion));
1474
    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMinorVersion));
1475
    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwBuildNumber));
1476
    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwPlatformId));
1477
    PyStructSequence_SET_ITEM(version, pos++, PyUnicode_FromWideChar(ver.szCSDVersion, -1));
1478
    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMajor));
1479
    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMinor));
1480
    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wSuiteMask));
1481
    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wProductType));
1482
1483
    realMajor = ver.dwMajorVersion;
1484
    realMinor = ver.dwMinorVersion;
1485
    realBuild = ver.dwBuildNumber;
1486
1487
    // GetVersion will lie if we are running in a compatibility mode.
1488
    // We need to read the version info from a system file resource
1489
    // to accurately identify the OS version. If we fail for any reason,
1490
    // just return whatever GetVersion said.
1491
    Py_BEGIN_ALLOW_THREADS
1492
    hKernel32 = GetModuleHandleW(L"kernel32.dll");
1493
    Py_END_ALLOW_THREADS
1494
    if (hKernel32 && GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH) &&
1495
        (verblock_size = GetFileVersionInfoSizeW(kernel32_path, NULL)) &&
1496
        (verblock = PyMem_RawMalloc(verblock_size))) {
1497
        VS_FIXEDFILEINFO *ffi;
1498
        UINT ffi_len;
1499
1500
        if (GetFileVersionInfoW(kernel32_path, 0, verblock_size, verblock) &&
1501
            VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) {
1502
            realMajor = HIWORD(ffi->dwProductVersionMS);
1503
            realMinor = LOWORD(ffi->dwProductVersionMS);
1504
            realBuild = HIWORD(ffi->dwProductVersionLS);
1505
        }
1506
        PyMem_RawFree(verblock);
1507
    }
1508
    PyStructSequence_SET_ITEM(version, pos++, Py_BuildValue("(kkk)",
1509
        realMajor,
1510
        realMinor,
1511
        realBuild
1512
    ));
1513
1514
    if (PyErr_Occurred()) {
1515
        Py_DECREF(version);
1516
        return NULL;
1517
    }
1518
    return version;
1519
}
1520
1521
#pragma warning(pop)
1522
1523
/*[clinic input]
1524
sys._enablelegacywindowsfsencoding
1525
1526
Changes the default filesystem encoding to mbcs:replace.
1527
1528
This is done for consistency with earlier versions of Python. See PEP
1529
529 for more information.
1530
1531
This is equivalent to defining the PYTHONLEGACYWINDOWSFSENCODING
1532
environment variable before launching Python.
1533
[clinic start generated code]*/
1534
1535
static PyObject *
1536
sys__enablelegacywindowsfsencoding_impl(PyObject *module)
1537
/*[clinic end generated code: output=f5c3855b45e24fe9 input=2bfa931a20704492]*/
1538
{
1539
    if (_PyUnicode_EnableLegacyWindowsFSEncoding() < 0) {
1540
        return NULL;
1541
    }
1542
    Py_RETURN_NONE;
1543
}
1544
1545
#endif /* MS_WINDOWS */
1546
1547
#ifdef HAVE_DLOPEN
1548
1549
/*[clinic input]
1550
sys.setdlopenflags
1551
1552
    flags as new_val: int
1553
    /
1554
1555
Set the flags used by the interpreter for dlopen calls.
1556
1557
This is used, for example, when the interpreter loads extension
1558
modules. Among other things, this will enable a lazy resolving of
1559
symbols when importing a module, if called as sys.setdlopenflags(0).
1560
To share symbols across extension modules, call as
1561
sys.setdlopenflags(os.RTLD_GLOBAL).  Symbolic names for the flag
1562
modules can be found in the os module (RTLD_xxx constants, e.g.
1563
os.RTLD_LAZY).
1564
[clinic start generated code]*/
1565
1566
static PyObject *
1567
sys_setdlopenflags_impl(PyObject *module, int new_val)
1568
/*[clinic end generated code: output=ec918b7fe0a37281 input=4c838211e857a77f]*/
1569
{
1570
    PyInterpreterState *interp = _PyInterpreterState_GET();
1571
    interp->dlopenflags = new_val;
1572
    Py_RETURN_NONE;
1573
}
1574
1575
1576
/*[clinic input]
1577
sys.getdlopenflags
1578
1579
Return the current value of the flags that are used for dlopen calls.
1580
1581
The flag constants are defined in the os module.
1582
[clinic start generated code]*/
1583
1584
static PyObject *
1585
sys_getdlopenflags_impl(PyObject *module)
1586
/*[clinic end generated code: output=e92cd1bc5005da6e input=dc4ea0899c53b4b6]*/
1587
{
1588
    PyInterpreterState *interp = _PyInterpreterState_GET();
1589
    return PyLong_FromLong(interp->dlopenflags);
1590
}
1591
1592
#endif  /* HAVE_DLOPEN */
1593
1594
#ifdef USE_MALLOPT
1595
/* Link with -lmalloc (or -lmpc) on an SGI */
1596
#include <malloc.h>
1597
1598
/*[clinic input]
1599
sys.mdebug
1600
1601
    flag: int
1602
    /
1603
[clinic start generated code]*/
1604
1605
static PyObject *
1606
sys_mdebug_impl(PyObject *module, int flag)
1607
/*[clinic end generated code: output=5431d545847c3637 input=151d150ae1636f8a]*/
1608
{
1609
    int flag;
1610
    mallopt(M_DEBUG, flag);
1611
    Py_RETURN_NONE;
1612
}
1613
#endif /* USE_MALLOPT */
1614
1615
size_t
1616
_PySys_GetSizeOf(PyObject *o)
1617
{
1618
    PyObject *res = NULL;
1619
    PyObject *method;
1620
    Py_ssize_t size;
1621
    PyThreadState *tstate = _PyThreadState_GET();
1622
1623
    /* Make sure the type is initialized. float gets initialized late */
1624
    if (PyType_Ready(Py_TYPE(o)) < 0) {
  Branch (1624:9): [True: 0, False: 295]
1625
        return (size_t)-1;
1626
    }
1627
1628
    method = _PyObject_LookupSpecial(o, &_Py_ID(__sizeof__));
1629
    if (method == NULL) {
  Branch (1629:9): [True: 1, False: 294]
1630
        if (!_PyErr_Occurred(tstate)) {
  Branch (1630:13): [True: 0, False: 1]
1631
            _PyErr_Format(tstate, PyExc_TypeError,
1632
                          "Type %.100s doesn't define __sizeof__",
1633
                          Py_TYPE(o)->tp_name);
1634
        }
1635
    }
1636
    else {
1637
        res = _PyObject_CallNoArgs(method);
1638
        Py_DECREF(method);
1639
    }
1640
1641
    if (res == NULL)
  Branch (1641:9): [True: 2, False: 293]
1642
        return (size_t)-1;
1643
1644
    size = PyLong_AsSsize_t(res);
1645
    Py_DECREF(res);
1646
    if (size == -1 && 
_PyErr_Occurred(tstate)6
)
  Branch (1646:9): [True: 6, False: 287]
  Branch (1646:23): [True: 5, False: 1]
1647
        return (size_t)-1;
1648
1649
    if (size < 0) {
  Branch (1649:9): [True: 2, False: 286]
1650
        _PyErr_SetString(tstate, PyExc_ValueError,
1651
                          "__sizeof__() should return >= 0");
1652
        return (size_t)-1;
1653
    }
1654
1655
    return (size_t)size + _PyType_PreHeaderSize(Py_TYPE(o));
1656
}
1657
1658
static PyObject *
1659
sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
1660
{
1661
    static char *kwlist[] = {"object", "default", 0};
1662
    size_t size;
1663
    PyObject *o, *dflt = NULL;
1664
    PyThreadState *tstate = _PyThreadState_GET();
1665
1666
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof",
  Branch (1666:9): [True: 0, False: 293]
1667
                                     kwlist, &o, &dflt)) {
1668
        return NULL;
1669
    }
1670
1671
    size = _PySys_GetSizeOf(o);
1672
1673
    if (size == (size_t)-1 && 
_PyErr_Occurred(tstate)9
) {
  Branch (1673:9): [True: 9, False: 284]
  Branch (1673:31): [True: 9, False: 0]
1674
        /* Has a default value been given */
1675
        if (dflt != NULL && 
_PyErr_ExceptionMatches(tstate, PyExc_TypeError)2
) {
  Branch (1675:13): [True: 2, False: 7]
  Branch (1675:29): [True: 2, False: 0]
1676
            _PyErr_Clear(tstate);
1677
            Py_INCREF(dflt);
1678
            return dflt;
1679
        }
1680
        else
1681
            return NULL;
1682
    }
1683
1684
    return PyLong_FromSize_t(size);
1685
}
1686
1687
PyDoc_STRVAR(getsizeof_doc,
1688
"getsizeof(object [, default]) -> int\n\
1689
\n\
1690
Return the size of object in bytes.");
1691
1692
/*[clinic input]
1693
sys.getrefcount -> Py_ssize_t
1694
1695
    object:  object
1696
    /
1697
1698
Return the reference count of object.
1699
1700
The count returned is generally one higher than you might expect,
1701
because it includes the (temporary) reference as an argument to
1702
getrefcount().
1703
[clinic start generated code]*/
1704
1705
static Py_ssize_t
1706
sys_getrefcount_impl(PyObject *module, PyObject *object)
1707
/*[clinic end generated code: output=5fd477f2264b85b2 input=bf474efd50a21535]*/
1708
{
1709
    return Py_REFCNT(object);
1710
}
1711
1712
#ifdef Py_REF_DEBUG
1713
/*[clinic input]
1714
sys.gettotalrefcount -> Py_ssize_t
1715
[clinic start generated code]*/
1716
1717
static Py_ssize_t
1718
sys_gettotalrefcount_impl(PyObject *module)
1719
/*[clinic end generated code: output=4103886cf17c25bc input=53b744faa5d2e4f6]*/
1720
{
1721
    return _Py_GetRefTotal();
1722
}
1723
1724
#endif /* Py_REF_DEBUG */
1725
1726
/*[clinic input]
1727
sys._getquickenedcount -> Py_ssize_t
1728
[clinic start generated code]*/
1729
1730
static Py_ssize_t
1731
sys__getquickenedcount_impl(PyObject *module)
1732
/*[clinic end generated code: output=1ab259e7f91248a2 input=249d448159eca912]*/
1733
{
1734
    return _Py_QuickenedCount;
1735
}
1736
1737
/*[clinic input]
1738
sys.getallocatedblocks -> Py_ssize_t
1739
1740
Return the number of memory blocks currently allocated.
1741
[clinic start generated code]*/
1742
1743
static Py_ssize_t
1744
sys_getallocatedblocks_impl(PyObject *module)
1745
/*[clinic end generated code: output=f0c4e873f0b6dcf7 input=dab13ee346a0673e]*/
1746
{
1747
    return _Py_GetAllocatedBlocks();
1748
}
1749
1750
1751
/*[clinic input]
1752
sys._getframe
1753
1754
    depth: int = 0
1755
    /
1756
1757
Return a frame object from the call stack.
1758
1759
If optional integer depth is given, return the frame object that many
1760
calls below the top of the stack.  If that is deeper than the call
1761
stack, ValueError is raised.  The default for depth is zero, returning
1762
the frame at the top of the call stack.
1763
1764
This function should be used for internal and specialized purposes
1765
only.
1766
[clinic start generated code]*/
1767
1768
static PyObject *
1769
sys__getframe_impl(PyObject *module, int depth)
1770
/*[clinic end generated code: output=d438776c04d59804 input=c1be8a6464b11ee5]*/
1771
{
1772
    PyThreadState *tstate = _PyThreadState_GET();
1773
    _PyInterpreterFrame *frame = tstate->cframe->current_frame;
1774
1775
    if (_PySys_Audit(tstate, "sys._getframe", NULL) < 0) {
  Branch (1775:9): [True: 0, False: 10.5k]
1776
        return NULL;
1777
    }
1778
1779
    if (frame != NULL) {
  Branch (1779:9): [True: 10.5k, False: 0]
1780
        while (depth > 0) {
  Branch (1780:16): [True: 9.51k, False: 10.5k]
1781
            frame = frame->previous;
1782
            if (frame == NULL) {
  Branch (1782:17): [True: 1, False: 9.51k]
1783
                break;
1784
            }
1785
            if (_PyFrame_IsIncomplete(frame)) {
  Branch (1785:17): [True: 0, False: 9.51k]
1786
                continue;
1787
            }
1788
            --depth;
1789
        }
1790
    }
1791
    if (frame == NULL) {
  Branch (1791:9): [True: 1, False: 10.5k]
1792
        _PyErr_SetString(tstate, PyExc_ValueError,
1793
                         "call stack is not deep enough");
1794
        return NULL;
1795
    }
1796
    return _Py_XNewRef((PyObject *)_PyFrame_GetFrameObject(frame));
1797
}
1798
1799
/*[clinic input]
1800
sys._current_frames
1801
1802
Return a dict mapping each thread's thread id to its current stack frame.
1803
1804
This function should be used for specialized purposes only.
1805
[clinic start generated code]*/
1806
1807
static PyObject *
1808
sys__current_frames_impl(PyObject *module)
1809
/*[clinic end generated code: output=d2a41ac0a0a3809a input=2a9049c5f5033691]*/
1810
{
1811
    return _PyThread_CurrentFrames();
1812
}
1813
1814
/*[clinic input]
1815
sys._current_exceptions
1816
1817
Return a dict mapping each thread's identifier to its current raised exception.
1818
1819
This function should be used for specialized purposes only.
1820
[clinic start generated code]*/
1821
1822
static PyObject *
1823
sys__current_exceptions_impl(PyObject *module)
1824
/*[clinic end generated code: output=2ccfd838c746f0ba input=0e91818fbf2edc1f]*/
1825
{
1826
    return _PyThread_CurrentExceptions();
1827
}
1828
1829
/*[clinic input]
1830
sys.call_tracing
1831
1832
    func: object
1833
    args as funcargs: object(subclass_of='&PyTuple_Type')
1834
    /
1835
1836
Call func(*args), while tracing is enabled.
1837
1838
The tracing state is saved, and restored afterwards.  This is intended
1839
to be called from a debugger from a checkpoint, to recursively debug
1840
some other code.
1841
[clinic start generated code]*/
1842
1843
static PyObject *
1844
sys_call_tracing_impl(PyObject *module, PyObject *func, PyObject *funcargs)
1845
/*[clinic end generated code: output=7e4999853cd4e5a6 input=5102e8b11049f92f]*/
1846
{
1847
    return _PyEval_CallTracing(func, funcargs);
1848
}
1849
1850
1851
#ifdef __cplusplus
1852
extern "C" {
1853
#endif
1854
1855
/*[clinic input]
1856
sys._debugmallocstats
1857
1858
Print summary info to stderr about the state of pymalloc's structures.
1859
1860
In Py_DEBUG mode, also perform some expensive internal consistency
1861
checks.
1862
[clinic start generated code]*/
1863
1864
static PyObject *
1865
sys__debugmallocstats_impl(PyObject *module)
1866
/*[clinic end generated code: output=ec3565f8c7cee46a input=33c0c9c416f98424]*/
1867
{
1868
#ifdef WITH_PYMALLOC
1869
    if (_PyObject_DebugMallocStats(stderr)) {
  Branch (1869:9): [True: 0, False: 0]
1870
        fputc('\n', stderr);
1871
    }
1872
#endif
1873
    _PyObject_DebugTypeStats(stderr);
1874
1875
    Py_RETURN_NONE;
1876
}
1877
1878
#ifdef Py_TRACE_REFS
1879
/* Defined in objects.c because it uses static globals in that file */
1880
extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
1881
#endif
1882
1883
#ifdef Py_STATS
1884
/* Defined in ceval.c because it uses static globals in that file */
1885
extern PyObject *_Py_GetDXProfile(PyObject *,  PyObject *);
1886
#endif
1887
1888
#ifdef __cplusplus
1889
}
1890
#endif
1891
1892
1893
/*[clinic input]
1894
sys._clear_type_cache
1895
1896
Clear the internal type lookup cache.
1897
[clinic start generated code]*/
1898
1899
static PyObject *
1900
sys__clear_type_cache_impl(PyObject *module)
1901
/*[clinic end generated code: output=20e48ca54a6f6971 input=127f3e04a8d9b555]*/
1902
{
1903
    PyType_ClearCache();
1904
    Py_RETURN_NONE;
1905
}
1906
1907
/*[clinic input]
1908
sys.is_finalizing
1909
1910
Return True if Python is exiting.
1911
[clinic start generated code]*/
1912
1913
static PyObject *
1914
sys_is_finalizing_impl(PyObject *module)
1915
/*[clinic end generated code: output=735b5ff7962ab281 input=f0df747a039948a5]*/
1916
{
1917
    return PyBool_FromLong(_Py_IsFinalizing());
1918
}
1919
1920
#ifdef Py_STATS
1921
/*[clinic input]
1922
sys._stats_on
1923
1924
Turns on stats gathering (stats gathering is on by default).
1925
[clinic start generated code]*/
1926
1927
static PyObject *
1928
sys__stats_on_impl(PyObject *module)
1929
/*[clinic end generated code: output=aca53eafcbb4d9fe input=8ddc6df94e484f3a]*/
1930
{
1931
    _py_stats = &_py_stats_struct;
1932
    Py_RETURN_NONE;
1933
}
1934
1935
/*[clinic input]
1936
sys._stats_off
1937
1938
Turns off stats gathering (stats gathering is on by default).
1939
[clinic start generated code]*/
1940
1941
static PyObject *
1942
sys__stats_off_impl(PyObject *module)
1943
/*[clinic end generated code: output=1534c1ee63812214 input=b3e50e71ecf29f66]*/
1944
{
1945
    _py_stats = NULL;
1946
    Py_RETURN_NONE;
1947
}
1948
1949
/*[clinic input]
1950
sys._stats_clear
1951
1952
Clears the stats.
1953
[clinic start generated code]*/
1954
1955
static PyObject *
1956
sys__stats_clear_impl(PyObject *module)
1957
/*[clinic end generated code: output=fb65a2525ee50604 input=3e03f2654f44da96]*/
1958
{
1959
    _Py_StatsClear();
1960
    Py_RETURN_NONE;
1961
}
1962
1963
/*[clinic input]
1964
sys._stats_dump
1965
1966
Dump stats to file, and clears the stats.
1967
[clinic start generated code]*/
1968
1969
static PyObject *
1970
sys__stats_dump_impl(PyObject *module)
1971
/*[clinic end generated code: output=79f796fb2b4ddf05 input=92346f16d64f6f95]*/
1972
{
1973
    _Py_PrintSpecializationStats(1);
1974
    _Py_StatsClear();
1975
    Py_RETURN_NONE;
1976
}
1977
1978
#endif
1979
1980
#ifdef ANDROID_API_LEVEL
1981
/*[clinic input]
1982
sys.getandroidapilevel
1983
1984
Return the build time API version of Android as an integer.
1985
[clinic start generated code]*/
1986
1987
static PyObject *
1988
sys_getandroidapilevel_impl(PyObject *module)
1989
/*[clinic end generated code: output=214abf183a1c70c1 input=3e6d6c9fcdd24ac6]*/
1990
{
1991
    return PyLong_FromLong(ANDROID_API_LEVEL);
1992
}
1993
#endif   /* ANDROID_API_LEVEL */
1994
1995
static PyMethodDef sys_methods[] = {
1996
    /* Might as well keep this in alphabetic order */
1997
    SYS_ADDAUDITHOOK_METHODDEF
1998
    {"audit", _PyCFunction_CAST(sys_audit), METH_FASTCALL, audit_doc },
1999
    {"breakpointhook", _PyCFunction_CAST(sys_breakpointhook),
2000
     METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc},
2001
    SYS__CLEAR_TYPE_CACHE_METHODDEF
2002
    SYS__CURRENT_FRAMES_METHODDEF
2003
    SYS__CURRENT_EXCEPTIONS_METHODDEF
2004
    SYS_DISPLAYHOOK_METHODDEF
2005
    SYS_EXCEPTION_METHODDEF
2006
    SYS_EXC_INFO_METHODDEF
2007
    SYS_EXCEPTHOOK_METHODDEF
2008
    SYS_EXIT_METHODDEF
2009
    SYS_GETDEFAULTENCODING_METHODDEF
2010
    SYS_GETDLOPENFLAGS_METHODDEF
2011
    SYS_GETALLOCATEDBLOCKS_METHODDEF
2012
#ifdef Py_STATS
2013
    {"getdxp", _Py_GetDXProfile, METH_VARARGS},
2014
#endif
2015
    SYS_GETFILESYSTEMENCODING_METHODDEF
2016
    SYS_GETFILESYSTEMENCODEERRORS_METHODDEF
2017
    SYS__GETQUICKENEDCOUNT_METHODDEF
2018
#ifdef Py_TRACE_REFS
2019
    {"getobjects", _Py_GetObjects, METH_VARARGS},
2020
#endif
2021
    SYS_GETTOTALREFCOUNT_METHODDEF
2022
    SYS_GETREFCOUNT_METHODDEF
2023
    SYS_GETRECURSIONLIMIT_METHODDEF
2024
    {"getsizeof", _PyCFunction_CAST(sys_getsizeof),
2025
     METH_VARARGS | METH_KEYWORDS, getsizeof_doc},
2026
    SYS__GETFRAME_METHODDEF
2027
    SYS_GETWINDOWSVERSION_METHODDEF
2028
    SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF
2029
    SYS_INTERN_METHODDEF
2030
    SYS_IS_FINALIZING_METHODDEF
2031
    SYS_MDEBUG_METHODDEF
2032
    SYS_SETSWITCHINTERVAL_METHODDEF
2033
    SYS_GETSWITCHINTERVAL_METHODDEF
2034
    SYS_SETDLOPENFLAGS_METHODDEF
2035
    {"setprofile", sys_setprofile, METH_O, setprofile_doc},
2036
    SYS_GETPROFILE_METHODDEF
2037
    SYS_SETRECURSIONLIMIT_METHODDEF
2038
    {"settrace", sys_settrace, METH_O, settrace_doc},
2039
    SYS_GETTRACE_METHODDEF
2040
    SYS_CALL_TRACING_METHODDEF
2041
    SYS__DEBUGMALLOCSTATS_METHODDEF
2042
    SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF
2043
    SYS_GET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF
2044
    {"set_asyncgen_hooks", _PyCFunction_CAST(sys_set_asyncgen_hooks),
2045
     METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc},
2046
    SYS_GET_ASYNCGEN_HOOKS_METHODDEF
2047
    SYS_GETANDROIDAPILEVEL_METHODDEF
2048
    SYS_UNRAISABLEHOOK_METHODDEF
2049
#ifdef Py_STATS
2050
    SYS__STATS_ON_METHODDEF
2051
    SYS__STATS_OFF_METHODDEF
2052
    SYS__STATS_CLEAR_METHODDEF
2053
    SYS__STATS_DUMP_METHODDEF
2054
#endif
2055
    {NULL, NULL}  // sentinel
2056
};
2057
2058
2059
static PyObject *
2060
list_builtin_module_names(void)
2061
{
2062
    PyObject *list = PyList_New(0);
2063
    if (list == NULL) {
  Branch (2063:9): [True: 0, False: 278]
2064
        return NULL;
2065
    }
2066
    
for (Py_ssize_t i = 0; 278
PyImport_Inittab[i].name != NULL;
i++8.62k
) {
  Branch (2066:28): [True: 8.62k, False: 278]
2067
        PyObject *name = PyUnicode_FromString(PyImport_Inittab[i].name);
2068
        if (name == NULL) {
  Branch (2068:13): [True: 0, False: 8.62k]
2069
            goto error;
2070
        }
2071
        if (PyList_Append(list, name) < 0) {
  Branch (2071:13): [True: 0, False: 8.62k]
2072
            Py_DECREF(name);
2073
            goto error;
2074
        }
2075
        Py_DECREF(name);
2076
    }
2077
    if (PyList_Sort(list) != 0) {
  Branch (2077:9): [True: 0, False: 278]
2078
        goto error;
2079
    }
2080
    PyObject *tuple = PyList_AsTuple(list);
2081
    Py_DECREF(list);
2082
    return tuple;
2083
2084
error:
2085
    Py_DECREF(list);
2086
    return NULL;
2087
}
2088
2089
2090
static PyObject *
2091
list_stdlib_module_names(void)
2092
{
2093
    Py_ssize_t len = Py_ARRAY_LENGTH(_Py_stdlib_module_names);
2094
    PyObject *names = PyTuple_New(len);
2095
    if (names == NULL) {
  Branch (2095:9): [True: 0, False: 278]
2096
        return NULL;
2097
    }
2098
2099
    
for (Py_ssize_t i = 0; 278
i < len;
i++84.7k
) {
  Branch (2099:28): [True: 84.7k, False: 278]
2100
        PyObject *name = PyUnicode_FromString(_Py_stdlib_module_names[i]);
2101
        if (name == NULL) {
  Branch (2101:13): [True: 0, False: 84.7k]
2102
            Py_DECREF(names);
2103
            return NULL;
2104
        }
2105
        PyTuple_SET_ITEM(names, i, name);
2106
    }
2107
2108
    PyObject *set = PyObject_CallFunction((PyObject *)&PyFrozenSet_Type,
2109
                                          "(O)", names);
2110
    Py_DECREF(names);
2111
    return set;
2112
}
2113
2114
2115
/* Pre-initialization support for sys.warnoptions and sys._xoptions
2116
 *
2117
 * Modern internal code paths:
2118
 *   These APIs get called after _Py_InitializeCore and get to use the
2119
 *   regular CPython list, dict, and unicode APIs.
2120
 *
2121
 * Legacy embedding code paths:
2122
 *   The multi-phase initialization API isn't public yet, so embedding
2123
 *   apps still need to be able configure sys.warnoptions and sys._xoptions
2124
 *   before they call Py_Initialize. To support this, we stash copies of
2125
 *   the supplied wchar * sequences in linked lists, and then migrate the
2126
 *   contents of those lists to the sys module in _PyInitializeCore.
2127
 *
2128
 */
2129
2130
struct _preinit_entry {
2131
    wchar_t *value;
2132
    struct _preinit_entry *next;
2133
};
2134
2135
typedef struct _preinit_entry *_Py_PreInitEntry;
2136
2137
static _Py_PreInitEntry _preinit_warnoptions = NULL;
2138
static _Py_PreInitEntry _preinit_xoptions = NULL;
2139
2140
static _Py_PreInitEntry
2141
_alloc_preinit_entry(const wchar_t *value)
2142
{
2143
    /* To get this to work, we have to initialize the runtime implicitly */
2144
    _PyRuntime_Initialize();
2145
2146
    /* Force default allocator, so we can ensure that it also gets used to
2147
     * destroy the linked list in _clear_preinit_entries.
2148
     */
2149
    PyMemAllocatorEx old_alloc;
2150
    _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2151
2152
    _Py_PreInitEntry node = PyMem_RawCalloc(1, sizeof(*node));
2153
    if (node != NULL) {
  Branch (2153:9): [True: 10, False: 0]
2154
        node->value = _PyMem_RawWcsdup(value);
2155
        if (node->value == NULL) {
  Branch (2155:13): [True: 0, False: 10]
2156
            PyMem_RawFree(node);
2157
            node = NULL;
2158
        };
2159
    };
2160
2161
    PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2162
    return node;
2163
}
2164
2165
static int
2166
_append_preinit_entry(_Py_PreInitEntry *optionlist, const wchar_t *value)
2167
{
2168
    _Py_PreInitEntry new_entry = _alloc_preinit_entry(value);
2169
    if (new_entry == NULL) {
  Branch (2169:9): [True: 0, False: 10]
2170
        return -1;
2171
    }
2172
    /* We maintain the linked list in this order so it's easy to play back
2173
     * the add commands in the same order later on in _Py_InitializeCore
2174
     */
2175
    _Py_PreInitEntry last_entry = *optionlist;
2176
    if (last_entry == NULL) {
  Branch (2176:9): [True: 6, False: 4]
2177
        *optionlist = new_entry;
2178
    } else {
2179
        while (last_entry->next != NULL) {
  Branch (2179:16): [True: 1, False: 4]
2180
            last_entry = last_entry->next;
2181
        }
2182
        last_entry->next = new_entry;
2183
    }
2184
    return 0;
2185
}
2186
2187
static void
2188
_clear_preinit_entries(_Py_PreInitEntry *optionlist)
2189
{
2190
    _Py_PreInitEntry current = *optionlist;
2191
    *optionlist = NULL;
2192
    /* Deallocate the nodes and their contents using the default allocator */
2193
    PyMemAllocatorEx old_alloc;
2194
    _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2195
    while (current != NULL) {
  Branch (2195:12): [True: 10, False: 223]
2196
        _Py_PreInitEntry next = current->next;
2197
        PyMem_RawFree(current->value);
2198
        PyMem_RawFree(current);
2199
        current = next;
2200
    }
2201
    PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2202
}
2203
2204
2205
PyStatus
2206
_PySys_ReadPreinitWarnOptions(PyWideStringList *options)
2207
{
2208
    PyStatus status;
2209
    _Py_PreInitEntry entry;
2210
2211
    for (entry = _preinit_warnoptions; entry != NULL; 
entry = entry->next6
) {
  Branch (2211:40): [True: 6, False: 111]
2212
        status = PyWideStringList_Append(options, entry->value);
2213
        if (_PyStatus_EXCEPTION(status)) {
2214
            return status;
2215
        }
2216
    }
2217
2218
    _clear_preinit_entries(&_preinit_warnoptions);
2219
    return _PyStatus_OK();
2220
}
2221
2222
2223
PyStatus
2224
_PySys_ReadPreinitXOptions(PyConfig *config)
2225
{
2226
    PyStatus status;
2227
    _Py_PreInitEntry entry;
2228
2229
    for (entry = _preinit_xoptions; entry != NULL; 
entry = entry->next3
) {
  Branch (2229:37): [True: 3, False: 111]
2230
        status = PyWideStringList_Append(&config->xoptions, entry->value);
2231
        if (_PyStatus_EXCEPTION(status)) {
2232
            return status;
2233
        }
2234
    }
2235
2236
    _clear_preinit_entries(&_preinit_xoptions);
2237
    return _PyStatus_OK();
2238
}
2239
2240
2241
static PyObject *
2242
get_warnoptions(PyThreadState *tstate)
2243
{
2244
    PyObject *warnoptions = _PySys_GetAttr(tstate, &_Py_ID(warnoptions));
2245
    if (warnoptions == NULL || !PyList_Check(warnoptions)) {
  Branch (2245:9): [True: 0, False: 0]
  Branch (2245:32): [True: 0, False: 0]
2246
        /* PEP432 TODO: we can reach this if warnoptions is NULL in the main
2247
        *  interpreter config. When that happens, we need to properly set
2248
         * the `warnoptions` reference in the main interpreter config as well.
2249
         *
2250
         * For Python 3.7, we shouldn't be able to get here due to the
2251
         * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit
2252
         * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig
2253
         * call optional for embedding applications, thus making this
2254
         * reachable again.
2255
         */
2256
        warnoptions = PyList_New(0);
2257
        if (warnoptions == NULL) {
  Branch (2257:13): [True: 0, False: 0]
2258
            return NULL;
2259
        }
2260
        if (sys_set_object(tstate->interp, &_Py_ID(warnoptions), warnoptions)) {
  Branch (2260:13): [True: 0, False: 0]
2261
            Py_DECREF(warnoptions);
2262
            return NULL;
2263
        }
2264
        Py_DECREF(warnoptions);
2265
    }
2266
    return warnoptions;
2267
}
2268
2269
void
2270
PySys_ResetWarnOptions(void)
2271
{
2272
    PyThreadState *tstate = _PyThreadState_GET();
2273
    if (tstate == NULL) {
  Branch (2273:9): [True: 1, False: 0]
2274
        _clear_preinit_entries(&_preinit_warnoptions);
2275
        return;
2276
    }
2277
2278
    PyObject *warnoptions = _PySys_GetAttr(tstate, &_Py_ID(warnoptions));
2279
    if (warnoptions == NULL || !PyList_Check(warnoptions))
  Branch (2279:9): [True: 0, False: 0]
  Branch (2279:32): [True: 0, False: 0]
2280
        return;
2281
    PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
2282
}
2283
2284
static int
2285
_PySys_AddWarnOptionWithError(PyThreadState *tstate, PyObject *option)
2286
{
2287
    PyObject *warnoptions = get_warnoptions(tstate);
2288
    if (warnoptions == NULL) {
  Branch (2288:9): [True: 0, False: 0]
2289
        return -1;
2290
    }
2291
    if (PyList_Append(warnoptions, option)) {
  Branch (2291:9): [True: 0, False: 0]
2292
        return -1;
2293
    }
2294
    return 0;
2295
}
2296
2297
void
2298
PySys_AddWarnOptionUnicode(PyObject *option)
2299
{
2300
    PyThreadState *tstate = _PyThreadState_GET();
2301
    if (_PySys_AddWarnOptionWithError(tstate, option) < 0) {
  Branch (2301:9): [True: 0, False: 0]
2302
        /* No return value, therefore clear error state if possible */
2303
        if (tstate) {
  Branch (2303:13): [True: 0, False: 0]
2304
            _PyErr_Clear(tstate);
2305
        }
2306
    }
2307
}
2308
2309
void
2310
PySys_AddWarnOption(const wchar_t *s)
2311
{
2312
    PyThreadState *tstate = _PyThreadState_GET();
2313
    if (tstate == NULL) {
  Branch (2313:9): [True: 7, False: 0]
2314
        _append_preinit_entry(&_preinit_warnoptions, s);
2315
        return;
2316
    }
2317
    PyObject *unicode;
2318
    unicode = PyUnicode_FromWideChar(s, -1);
2319
    if (unicode == NULL)
  Branch (2319:9): [True: 0, False: 0]
2320
        return;
2321
_Py_COMP_DIAG_PUSH
2322
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
2323
    PySys_AddWarnOptionUnicode(unicode);
2324
_Py_COMP_DIAG_POP
2325
    Py_DECREF(unicode);
2326
}
2327
2328
int
2329
PySys_HasWarnOptions(void)
2330
{
2331
    PyThreadState *tstate = _PyThreadState_GET();
2332
    PyObject *warnoptions = _PySys_GetAttr(tstate, &_Py_ID(warnoptions));
2333
    return (warnoptions != NULL && PyList_Check(warnoptions)
  Branch (2333:13): [True: 0, False: 0]
2334
            && PyList_GET_SIZE(warnoptions) > 0);
  Branch (2334:16): [True: 0, False: 0]
2335
}
2336
2337
static PyObject *
2338
get_xoptions(PyThreadState *tstate)
2339
{
2340
    PyObject *xoptions = _PySys_GetAttr(tstate, &_Py_ID(_xoptions));
2341
    if (xoptions == NULL || !PyDict_Check(xoptions)) {
  Branch (2341:9): [True: 0, False: 0]
  Branch (2341:29): [True: 0, False: 0]
2342
        /* PEP432 TODO: we can reach this if xoptions is NULL in the main
2343
        *  interpreter config. When that happens, we need to properly set
2344
         * the `xoptions` reference in the main interpreter config as well.
2345
         *
2346
         * For Python 3.7, we shouldn't be able to get here due to the
2347
         * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit
2348
         * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig
2349
         * call optional for embedding applications, thus making this
2350
         * reachable again.
2351
         */
2352
        xoptions = PyDict_New();
2353
        if (xoptions == NULL) {
  Branch (2353:13): [True: 0, False: 0]
2354
            return NULL;
2355
        }
2356
        if (sys_set_object(tstate->interp, &_Py_ID(_xoptions), xoptions)) {
  Branch (2356:13): [True: 0, False: 0]
2357
            Py_DECREF(xoptions);
2358
            return NULL;
2359
        }
2360
        Py_DECREF(xoptions);
2361
    }
2362
    return xoptions;
2363
}
2364
2365
static int
2366
_PySys_AddXOptionWithError(const wchar_t *s)
2367
{
2368
    PyObject *name = NULL, *value = NULL;
2369
2370
    PyThreadState *tstate = _PyThreadState_GET();
2371
    PyObject *opts = get_xoptions(tstate);
2372
    if (opts == NULL) {
  Branch (2372:9): [True: 0, False: 0]
2373
        goto error;
2374
    }
2375
2376
    const wchar_t *name_end = wcschr(s, L'=');
2377
    if (!name_end) {
  Branch (2377:9): [True: 0, False: 0]
2378
        name = PyUnicode_FromWideChar(s, -1);
2379
        value = Py_True;
2380
        Py_INCREF(value);
2381
    }
2382
    else {
2383
        name = PyUnicode_FromWideChar(s, name_end - s);
2384
        value = PyUnicode_FromWideChar(name_end + 1, -1);
2385
    }
2386
    if (name == NULL || value == NULL) {
  Branch (2386:9): [True: 0, False: 0]
  Branch (2386:25): [True: 0, False: 0]
2387
        goto error;
2388
    }
2389
    if (PyDict_SetItem(opts, name, value) < 0) {
  Branch (2389:9): [True: 0, False: 0]
2390
        goto error;
2391
    }
2392
    Py_DECREF(name);
2393
    Py_DECREF(value);
2394
    return 0;
2395
2396
error:
2397
    Py_XDECREF(name);
2398
    Py_XDECREF(value);
2399
    return -1;
2400
}
2401
2402
void
2403
PySys_AddXOption(const wchar_t *s)
2404
{
2405
    PyThreadState *tstate = _PyThreadState_GET();
2406
    if (tstate == NULL) {
  Branch (2406:9): [True: 3, False: 0]
2407
        _append_preinit_entry(&_preinit_xoptions, s);
2408
        return;
2409
    }
2410
    if (_PySys_AddXOptionWithError(s) < 0) {
  Branch (2410:9): [True: 0, False: 0]
2411
        /* No return value, therefore clear error state if possible */
2412
        _PyErr_Clear(tstate);
2413
    }
2414
}
2415
2416
PyObject *
2417
PySys_GetXOptions(void)
2418
{
2419
    PyThreadState *tstate = _PyThreadState_GET();
2420
    return get_xoptions(tstate);
2421
}
2422
2423
/* XXX This doc string is too long to be a single string literal in VC++ 5.0.
2424
   Two literals concatenated works just fine.  If you have a K&R compiler
2425
   or other abomination that however *does* understand longer strings,
2426
   get rid of the !!! comment in the middle and the quotes that surround it. */
2427
PyDoc_VAR(sys_doc) =
2428
PyDoc_STR(
2429
"This module provides access to some objects used or maintained by the\n\
2430
interpreter and to functions that interact strongly with the interpreter.\n\
2431
\n\
2432
Dynamic objects:\n\
2433
\n\
2434
argv -- command line arguments; argv[0] is the script pathname if known\n\
2435
path -- module search path; path[0] is the script directory, else ''\n\
2436
modules -- dictionary of loaded modules\n\
2437
\n\
2438
displayhook -- called to show results in an interactive session\n\
2439
excepthook -- called to handle any uncaught exception other than SystemExit\n\
2440
  To customize printing in an interactive session or to install a custom\n\
2441
  top-level exception handler, assign other functions to replace these.\n\
2442
\n\
2443
stdin -- standard input file object; used by input()\n\
2444
stdout -- standard output file object; used by print()\n\
2445
stderr -- standard error object; used for error messages\n\
2446
  By assigning other file objects (or objects that behave like files)\n\
2447
  to these, it is possible to redirect all of the interpreter's I/O.\n\
2448
\n\
2449
last_type -- type of last uncaught exception\n\
2450
last_value -- value of last uncaught exception\n\
2451
last_traceback -- traceback of last uncaught exception\n\
2452
  These three are only available in an interactive session after a\n\
2453
  traceback has been printed.\n\
2454
"
2455
)
2456
/* concatenating string here */
2457
PyDoc_STR(
2458
"\n\
2459
Static objects:\n\
2460
\n\
2461
builtin_module_names -- tuple of module names built into this interpreter\n\
2462
copyright -- copyright notice pertaining to this interpreter\n\
2463
exec_prefix -- prefix used to find the machine-specific Python library\n\
2464
executable -- absolute path of the executable binary of the Python interpreter\n\
2465
float_info -- a named tuple with information about the float implementation.\n\
2466
float_repr_style -- string indicating the style of repr() output for floats\n\
2467
hash_info -- a named tuple with information about the hash algorithm.\n\
2468
hexversion -- version information encoded as a single integer\n\
2469
implementation -- Python implementation information.\n\
2470
int_info -- a named tuple with information about the int implementation.\n\
2471
maxsize -- the largest supported length of containers.\n\
2472
maxunicode -- the value of the largest Unicode code point\n\
2473
platform -- platform identifier\n\
2474
prefix -- prefix used to find the Python library\n\
2475
thread_info -- a named tuple with information about the thread implementation.\n\
2476
version -- the version of this interpreter as a string\n\
2477
version_info -- version information as a named tuple\n\
2478
"
2479
)
2480
#ifdef MS_COREDLL
2481
/* concatenating string here */
2482
PyDoc_STR(
2483
"dllhandle -- [Windows only] integer handle of the Python DLL\n\
2484
winver -- [Windows only] version number of the Python DLL\n\
2485
"
2486
)
2487
#endif /* MS_COREDLL */
2488
#ifdef MS_WINDOWS
2489
/* concatenating string here */
2490
PyDoc_STR(
2491
"_enablelegacywindowsfsencoding -- [Windows only]\n\
2492
"
2493
)
2494
#endif
2495
PyDoc_STR(
2496
"__stdin__ -- the original stdin; don't touch!\n\
2497
__stdout__ -- the original stdout; don't touch!\n\
2498
__stderr__ -- the original stderr; don't touch!\n\
2499
__displayhook__ -- the original displayhook; don't touch!\n\
2500
__excepthook__ -- the original excepthook; don't touch!\n\
2501
\n\
2502
Functions:\n\
2503
\n\
2504
displayhook() -- print an object to the screen, and save it in builtins._\n\
2505
excepthook() -- print an exception and its traceback to sys.stderr\n\
2506
exception() -- return the current thread's active exception\n\
2507
exc_info() -- return information about the current thread's active exception\n\
2508
exit() -- exit the interpreter by raising SystemExit\n\
2509
getdlopenflags() -- returns flags to be used for dlopen() calls\n\
2510
getprofile() -- get the global profiling function\n\
2511
getrefcount() -- return the reference count for an object (plus one :-)\n\
2512
getrecursionlimit() -- return the max recursion depth for the interpreter\n\
2513
getsizeof() -- return the size of an object in bytes\n\
2514
gettrace() -- get the global debug tracing function\n\
2515
setdlopenflags() -- set the flags to be used for dlopen() calls\n\
2516
setprofile() -- set the global profiling function\n\
2517
setrecursionlimit() -- set the max recursion depth for the interpreter\n\
2518
settrace() -- set the global debug tracing function\n\
2519
"
2520
)
2521
/* end of sys_doc */ ;
2522
2523
2524
PyDoc_STRVAR(flags__doc__,
2525
"sys.flags\n\
2526
\n\
2527
Flags provided through command line arguments or environment vars.");
2528
2529
static PyTypeObject FlagsType;
2530
2531
static PyStructSequence_Field flags_fields[] = {
2532
    {"debug",                   "-d"},
2533
    {"inspect",                 "-i"},
2534
    {"interactive",             "-i"},
2535
    {"optimize",                "-O or -OO"},
2536
    {"dont_write_bytecode",     "-B"},
2537
    {"no_user_site",            "-s"},
2538
    {"no_site",                 "-S"},
2539
    {"ignore_environment",      "-E"},
2540
    {"verbose",                 "-v"},
2541
    {"bytes_warning",           "-b"},
2542
    {"quiet",                   "-q"},
2543
    {"hash_randomization",      "-R"},
2544
    {"isolated",                "-I"},
2545
    {"dev_mode",                "-X dev"},
2546
    {"utf8_mode",               "-X utf8"},
2547
    {"warn_default_encoding",   "-X warn_default_encoding"},
2548
    {"safe_path", "-P"},
2549
    {0}
2550
};
2551
2552
static PyStructSequence_Desc flags_desc = {
2553
    "sys.flags",        /* name */
2554
    flags__doc__,       /* doc */
2555
    flags_fields,       /* fields */
2556
    17
2557
};
2558
2559
static int
2560
set_flags_from_config(PyInterpreterState *interp, PyObject *flags)
2561
{
2562
    const PyPreConfig *preconfig = &interp->runtime->preconfig;
2563
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);
2564
2565
    // _PySys_UpdateConfig() modifies sys.flags in-place:
2566
    // Py_XDECREF() is needed in this case.
2567
    Py_ssize_t pos = 0;
2568
#define SetFlagObj(expr) \
2569
    do { \
2570
        PyObject *value = (
expr564
); \
2571
        if (value == NULL) { \
2572
            return -1; \
2573
        } \
2574
        Py_XDECREF(PyStructSequence_GET_ITEM(flags, pos)); \
2575
        PyStructSequence_SET_ITEM(flags, pos, value); \
2576
        pos++; \
2577
    } while (0)
2578
#define SetFlag(expr) SetFlagObj(PyLong_FromLong(expr))
2579
2580
    SetFlag(config->parser_debug);
2581
    SetFlag(config->inspect);
2582
    SetFlag(config->interactive);
2583
    SetFlag(config->optimization_level);
2584
    SetFlag(!config->write_bytecode);
2585
    SetFlag(!config->user_site_directory);
2586
    SetFlag(!config->site_import);
2587
    SetFlag(!config->use_environment);
2588
    SetFlag(config->verbose);
2589
    SetFlag(config->bytes_warning);
2590
    SetFlag(config->quiet);
2591
    SetFlag(config->use_hash_seed == 0 || config->hash_seed != 0);
2592
    SetFlag(config->isolated);
2593
    SetFlagObj(PyBool_FromLong(config->dev_mode));
2594
    SetFlag(preconfig->utf8_mode);
2595
    SetFlag(config->warn_default_encoding);
2596
    SetFlagObj(PyBool_FromLong(config->safe_path));
2597
#undef SetFlagObj
2598
#undef SetFlag
2599
    return 0;
2600
}
2601
2602
2603
static PyObject*
2604
make_flags(PyInterpreterState *interp)
2605
{
2606
    PyObject *flags = PyStructSequence_New(&FlagsType);
2607
    if (flags == NULL) {
  Branch (2607:9): [True: 0, False: 278]
2608
        return NULL;
2609
    }
2610
2611
    if (set_flags_from_config(interp, flags) < 0) {
  Branch (2611:9): [True: 0, False: 278]
2612
        Py_DECREF(flags);
2613
        return NULL;
2614
    }
2615
    return flags;
2616
}
2617
2618
2619
PyDoc_STRVAR(version_info__doc__,
2620
"sys.version_info\n\
2621
\n\
2622
Version information as a named tuple.");
2623
2624
static PyTypeObject VersionInfoType;
2625
2626
static PyStructSequence_Field version_info_fields[] = {
2627
    {"major", "Major release number"},
2628
    {"minor", "Minor release number"},
2629
    {"micro", "Patch release number"},
2630
    {"releaselevel", "'alpha', 'beta', 'candidate', or 'final'"},
2631
    {"serial", "Serial release number"},
2632
    {0}
2633
};
2634
2635
static PyStructSequence_Desc version_info_desc = {
2636
    "sys.version_info",     /* name */
2637
    version_info__doc__,    /* doc */
2638
    version_info_fields,    /* fields */
2639
    5
2640
};
2641
2642
static PyObject *
2643
make_version_info(PyThreadState *tstate)
2644
{
2645
    PyObject *version_info;
2646
    char *s;
2647
    int pos = 0;
2648
2649
    version_info = PyStructSequence_New(&VersionInfoType);
2650
    if (version_info == NULL) {
  Branch (2650:9): [True: 0, False: 278]
2651
        return NULL;
2652
    }
2653
2654
    /*
2655
     * These release level checks are mutually exclusive and cover
2656
     * the field, so don't get too fancy with the pre-processor!
2657
     */
2658
#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
2659
    s = "alpha";
2660
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
2661
    s = "beta";
2662
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
2663
    s = "candidate";
2664
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
2665
    s = "final";
2666
#endif
2667
2668
#define SetIntItem(flag) \
2669
    PyStructSequence_SET_ITEM(version_info, pos++, PyLong_FromLong(flag))
2670
#define SetStrItem(flag) \
2671
    PyStructSequence_SET_ITEM(version_info, pos++, PyUnicode_FromString(flag))
2672
2673
    SetIntItem(PY_MAJOR_VERSION);
2674
    SetIntItem(PY_MINOR_VERSION);
2675
    SetIntItem(PY_MICRO_VERSION);
2676
    SetStrItem(s);
2677
    SetIntItem(PY_RELEASE_SERIAL);
2678
#undef SetIntItem
2679
#undef SetStrItem
2680
2681
    if (_PyErr_Occurred(tstate)) {
  Branch (2681:9): [True: 0, False: 278]
2682
        Py_CLEAR(version_info);
2683
        return NULL;
2684
    }
2685
    return version_info;
2686
}
2687
2688
/* sys.implementation values */
2689
#define NAME "cpython"
2690
const char *_PySys_ImplName = NAME;
2691
#define MAJOR Py_STRINGIFY(PY_MAJOR_VERSION)
2692
#define MINOR Py_STRINGIFY(PY_MINOR_VERSION)
2693
#define TAG NAME "-" MAJOR MINOR
2694
const char *_PySys_ImplCacheTag = TAG;
2695
#undef NAME
2696
#undef MAJOR
2697
#undef MINOR
2698
#undef TAG
2699
2700
static PyObject *
2701
make_impl_info(PyObject *version_info)
2702
{
2703
    int res;
2704
    PyObject *impl_info, *value, *ns;
2705
2706
    impl_info = PyDict_New();
2707
    if (impl_info == NULL)
  Branch (2707:9): [True: 0, False: 278]
2708
        return NULL;
2709
2710
    /* populate the dict */
2711
2712
    value = PyUnicode_FromString(_PySys_ImplName);
2713
    if (value == NULL)
  Branch (2713:9): [True: 0, False: 278]
2714
        goto error;
2715
    res = PyDict_SetItemString(impl_info, "name", value);
2716
    Py_DECREF(value);
2717
    if (res < 0)
  Branch (2717:9): [True: 0, False: 278]
2718
        goto error;
2719
2720
    value = PyUnicode_FromString(_PySys_ImplCacheTag);
2721
    if (value == NULL)
  Branch (2721:9): [True: 0, False: 278]
2722
        goto error;
2723
    res = PyDict_SetItemString(impl_info, "cache_tag", value);
2724
    Py_DECREF(value);
2725
    if (res < 0)
  Branch (2725:9): [True: 0, False: 278]
2726
        goto error;
2727
2728
    res = PyDict_SetItemString(impl_info, "version", version_info);
2729
    if (res < 0)
  Branch (2729:9): [True: 0, False: 278]
2730
        goto error;
2731
2732
    value = PyLong_FromLong(PY_VERSION_HEX);
2733
    if (value == NULL)
  Branch (2733:9): [True: 0, False: 278]
2734
        goto error;
2735
    res = PyDict_SetItemString(impl_info, "hexversion", value);
2736
    Py_DECREF(value);
2737
    if (res < 0)
  Branch (2737:9): [True: 0, False: 278]
2738
        goto error;
2739
2740
#ifdef MULTIARCH
2741
    value = PyUnicode_FromString(MULTIARCH);
2742
    if (value == NULL)
  Branch (2742:9): [True: 0, False: 278]
2743
        goto error;
2744
    res = PyDict_SetItemString(impl_info, "_multiarch", value);
2745
    Py_DECREF(value);
2746
    if (res < 0)
  Branch (2746:9): [True: 0, False: 278]
2747
        goto error;
2748
#endif
2749
2750
    /* dict ready */
2751
2752
    ns = _PyNamespace_New(impl_info);
2753
    Py_DECREF(impl_info);
2754
    return ns;
2755
2756
error:
2757
    Py_CLEAR(impl_info);
2758
    return NULL;
2759
}
2760
2761
#ifdef __EMSCRIPTEN__
2762
2763
PyDoc_STRVAR(emscripten_info__doc__,
2764
"sys._emscripten_info\n\
2765
\n\
2766
WebAssembly Emscripten platform information.");
2767
2768
static PyTypeObject *EmscriptenInfoType;
2769
2770
static PyStructSequence_Field emscripten_info_fields[] = {
2771
    {"emscripten_version", "Emscripten version (major, minor, micro)"},
2772
    {"runtime", "Runtime (Node.JS version, browser user agent)"},
2773
    {"pthreads", "pthread support"},
2774
    {"shared_memory", "shared memory support"},
2775
    {0}
2776
};
2777
2778
static PyStructSequence_Desc emscripten_info_desc = {
2779
    "sys._emscripten_info",     /* name */
2780
    emscripten_info__doc__ ,    /* doc */
2781
    emscripten_info_fields,     /* fields */
2782
    4
2783
};
2784
2785
EM_JS(char *, _Py_emscripten_runtime, (void), {
2786
    var info;
2787
    if (typeof navigator == 'object') {
2788
        info = navigator.userAgent;
2789
    } else if (typeof process == 'object') {
2790
        info = "Node.js ".concat(process.version)
2791
    } else {
2792
        info = "UNKNOWN"
2793
    }
2794
    var len = lengthBytesUTF8(info) + 1;
2795
    var res = _malloc(len);
2796
    stringToUTF8(info, res, len);
2797
    return res;
2798
});
2799
2800
static PyObject *
2801
make_emscripten_info(void)
2802
{
2803
    PyObject *emscripten_info = NULL;
2804
    PyObject *version = NULL;
2805
    char *ua;
2806
    int pos = 0;
2807
2808
    emscripten_info = PyStructSequence_New(EmscriptenInfoType);
2809
    if (emscripten_info == NULL) {
2810
        return NULL;
2811
    }
2812
2813
    version = Py_BuildValue("(iii)",
2814
        __EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__);
2815
    if (version == NULL) {
2816
        goto error;
2817
    }
2818
    PyStructSequence_SET_ITEM(emscripten_info, pos++, version);
2819
2820
    ua = _Py_emscripten_runtime();
2821
    if (ua != NULL) {
2822
        PyObject *oua = PyUnicode_DecodeUTF8(ua, strlen(ua), "strict");
2823
        free(ua);
2824
        if (oua == NULL) {
2825
            goto error;
2826
        }
2827
        PyStructSequence_SET_ITEM(emscripten_info, pos++, oua);
2828
    } else {
2829
        Py_INCREF(Py_None);
2830
        PyStructSequence_SET_ITEM(emscripten_info, pos++, Py_None);
2831
    }
2832
2833
#define SetBoolItem(flag) \
2834
    PyStructSequence_SET_ITEM(emscripten_info, pos++, PyBool_FromLong(flag))
2835
2836
#ifdef __EMSCRIPTEN_PTHREADS__
2837
    SetBoolItem(1);
2838
#else
2839
    SetBoolItem(0);
2840
#endif
2841
2842
#ifdef __EMSCRIPTEN_SHARED_MEMORY__
2843
    SetBoolItem(1);
2844
#else
2845
    SetBoolItem(0);
2846
#endif
2847
2848
#undef SetBoolItem
2849
2850
    if (PyErr_Occurred()) {
2851
        goto error;
2852
    }
2853
    return emscripten_info;
2854
2855
  error:
2856
    Py_CLEAR(emscripten_info);
2857
    return NULL;
2858
}
2859
2860
#endif // __EMSCRIPTEN__
2861
2862
static struct PyModuleDef sysmodule = {
2863
    PyModuleDef_HEAD_INIT,
2864
    "sys",
2865
    sys_doc,
2866
    -1, /* multiple "initialization" just copies the module dict. */
2867
    sys_methods,
2868
    NULL,
2869
    NULL,
2870
    NULL,
2871
    NULL
2872
};
2873
2874
/* Updating the sys namespace, returning NULL pointer on error */
2875
#define SET_SYS(key, value)                                \
2876
    do {                                                   \
2877
        PyObject *v = (value);                             \
2878
        if (v == NULL) {                                   \
2879
            goto err_occurred;                             \
2880
        }                                                  \
2881
        res = PyDict_SetItemString(sysdict, key, v);       \
2882
        Py_DECREF(v);                                      \
2883
        if (res < 0) {                                     \
2884
            goto err_occurred;                             \
2885
        }                                                  \
2886
    } while (0)
2887
2888
#define SET_SYS_FROM_STRING(key, value) \
2889
        SET_SYS(key, PyUnicode_FromString(value))
2890
2891
static PyStatus
2892
_PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
2893
{
2894
    PyObject *version_info;
2895
    int res;
2896
2897
    /* stdin/stdout/stderr are set in pylifecycle.c */
2898
2899
#define COPY_SYS_ATTR(tokey, fromkey) \
2900
        SET_SYS(tokey, PyMapping_GetItemString(sysdict, fromkey))
2901
2902
    COPY_SYS_ATTR("__displayhook__", "displayhook");
2903
    COPY_SYS_ATTR("__excepthook__", "excepthook");
2904
    COPY_SYS_ATTR("__breakpointhook__", "breakpointhook");
2905
    COPY_SYS_ATTR("__unraisablehook__", "unraisablehook");
2906
2907
#undef COPY_SYS_ATTR
2908
2909
    SET_SYS_FROM_STRING("version", Py_GetVersion());
2910
    SET_SYS("hexversion", PyLong_FromLong(PY_VERSION_HEX));
2911
    SET_SYS("_git", Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(),
2912
                                  _Py_gitversion()));
2913
    SET_SYS_FROM_STRING("_framework", _PYTHONFRAMEWORK);
2914
    SET_SYS("api_version", PyLong_FromLong(PYTHON_API_VERSION));
2915
    SET_SYS_FROM_STRING("copyright", Py_GetCopyright());
2916
    SET_SYS_FROM_STRING("platform", Py_GetPlatform());
2917
    SET_SYS("maxsize", PyLong_FromSsize_t(PY_SSIZE_T_MAX));
2918
    SET_SYS("float_info", PyFloat_GetInfo());
2919
    SET_SYS("int_info", PyLong_GetInfo());
2920
    /* initialize hash_info */
2921
    if (Hash_InfoType.tp_name == NULL) {
  Branch (2921:9): [True: 107, False: 171]
2922
        if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0) {
  Branch (2922:13): [True: 0, False: 107]
2923
            goto type_init_failed;
2924
        }
2925
    }
2926
    SET_SYS("hash_info", get_hash_info(tstate));
2927
    SET_SYS("maxunicode", PyLong_FromLong(0x10FFFF));
2928
    SET_SYS("builtin_module_names", list_builtin_module_names());
2929
    SET_SYS("stdlib_module_names", list_stdlib_module_names());
2930
#if PY_BIG_ENDIAN
2931
    SET_SYS_FROM_STRING("byteorder", "big");
2932
#else
2933
    SET_SYS_FROM_STRING("byteorder", "little");
2934
#endif
2935
2936
#ifdef MS_COREDLL
2937
    SET_SYS("dllhandle", PyLong_FromVoidPtr(PyWin_DLLhModule));
2938
    SET_SYS_FROM_STRING("winver", PyWin_DLLVersionString);
2939
#endif
2940
#ifdef ABIFLAGS
2941
    SET_SYS_FROM_STRING("abiflags", ABIFLAGS);
2942
#endif
2943
2944
    /* version_info */
2945
    if (VersionInfoType.tp_name == NULL) {
  Branch (2945:9): [True: 107, False: 171]
2946
        if (_PyStructSequence_InitType(&VersionInfoType,
  Branch (2946:13): [True: 0, False: 107]
2947
                                       &version_info_desc,
2948
                                       Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) {
2949
            goto type_init_failed;
2950
        }
2951
    }
2952
    version_info = make_version_info(tstate);
2953
    SET_SYS("version_info", version_info);
2954
2955
    /* implementation */
2956
    SET_SYS("implementation", make_impl_info(version_info));
2957
2958
    // sys.flags: updated in-place later by _PySys_UpdateConfig()
2959
    if (FlagsType.tp_name == 0) {
  Branch (2959:9): [True: 107, False: 171]
2960
        if (_PyStructSequence_InitType(&FlagsType, &flags_desc,
  Branch (2960:13): [True: 0, False: 107]
2961
                                       Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) {
2962
            goto type_init_failed;
2963
        }
2964
    }
2965
    SET_SYS("flags", make_flags(tstate->interp));
2966
2967
#if defined(MS_WINDOWS)
2968
    /* getwindowsversion */
2969
    if (WindowsVersionType.tp_name == 0) {
2970
        if (_PyStructSequence_InitType(&WindowsVersionType,
2971
                                       &windows_version_desc,
2972
                                       Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) {
2973
            goto type_init_failed;
2974
        }
2975
    }
2976
2977
    SET_SYS_FROM_STRING("_vpath", VPATH);
2978
#endif
2979
2980
    /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */
2981
#if _PY_SHORT_FLOAT_REPR == 1
2982
    SET_SYS_FROM_STRING("float_repr_style", "short");
2983
#else
2984
    SET_SYS_FROM_STRING("float_repr_style", "legacy");
2985
#endif
2986
2987
    SET_SYS("thread_info", PyThread_GetInfo());
2988
2989
    /* initialize asyncgen_hooks */
2990
    if (AsyncGenHooksType.tp_name == NULL) {
  Branch (2990:9): [True: 107, False: 171]
2991
        if (PyStructSequence_InitType2(
  Branch (2991:13): [True: 0, False: 107]
2992
                &AsyncGenHooksType, &asyncgen_hooks_desc) < 0) {
2993
            goto type_init_failed;
2994
        }
2995
    }
2996
2997
#ifdef __EMSCRIPTEN__
2998
    if (EmscriptenInfoType == NULL) {
2999
        EmscriptenInfoType = PyStructSequence_NewType(&emscripten_info_desc);
3000
        if (EmscriptenInfoType == NULL) {
3001
            goto type_init_failed;
3002
        }
3003
    }
3004
    SET_SYS("_emscripten_info", make_emscripten_info());
3005
#endif
3006
3007
    /* adding sys.path_hooks and sys.path_importer_cache */
3008
    SET_SYS("meta_path", PyList_New(0));
3009
    SET_SYS("path_importer_cache", PyDict_New());
3010
    SET_SYS("path_hooks", PyList_New(0));
3011
3012
    if (_PyErr_Occurred(tstate)) {
  Branch (3012:9): [True: 0, False: 278]
3013
        goto err_occurred;
3014
    }
3015
    return _PyStatus_OK();
3016
3017
type_init_failed:
3018
    return _PyStatus_ERR("failed to initialize a type");
3019
3020
err_occurred:
3021
    return _PyStatus_ERR("can't initialize sys module");
3022
}
3023
3024
static int
3025
sys_add_xoption(PyObject *opts, const wchar_t *s)
3026
{
3027
    PyObject *name, *value;
3028
3029
    const wchar_t *name_end = wcschr(s, L'=');
3030
    if (!name_end) {
  Branch (3030:9): [True: 7, False: 6]
3031
        name = PyUnicode_FromWideChar(s, -1);
3032
        value = Py_True;
3033
        Py_INCREF(value);
3034
    }
3035
    else {
3036
        name = PyUnicode_FromWideChar(s, name_end - s);
3037
        value = PyUnicode_FromWideChar(name_end + 1, -1);
3038
    }
3039
    if (name == NULL || value == NULL) {
  Branch (3039:9): [True: 0, False: 13]
  Branch (3039:25): [True: 0, False: 13]
3040
        goto error;
3041
    }
3042
    if (PyDict_SetItem(opts, name, value) < 0) {
  Branch (3042:9): [True: 0, False: 13]
3043
        goto error;
3044
    }
3045
    Py_DECREF(name);
3046
    Py_DECREF(value);
3047
    return 0;
3048
3049
error:
3050
    Py_XDECREF(name);
3051
    Py_XDECREF(value);
3052
    return -1;
3053
}
3054
3055
3056
static PyObject*
3057
sys_create_xoptions_dict(const PyConfig *config)
3058
{
3059
    Py_ssize_t nxoption = config->xoptions.length;
3060
    wchar_t * const * xoptions = config->xoptions.items;
3061
    PyObject *dict = PyDict_New();
3062
    if (dict == NULL) {
  Branch (3062:9): [True: 0, False: 280]
3063
        return NULL;
3064
    }
3065
3066
    
for (Py_ssize_t i=0; 280
i < nxoption;
i++13
) {
  Branch (3066:26): [True: 13, False: 280]
3067
        const wchar_t *option = xoptions[i];
3068
        if (sys_add_xoption(dict, option) < 0) {
  Branch (3068:13): [True: 0, False: 13]
3069
            Py_DECREF(dict);
3070
            return NULL;
3071
        }
3072
    }
3073
3074
    return dict;
3075
}
3076
3077
3078
// Update sys attributes for a new PyConfig configuration.
3079
// This function also adds attributes that _PySys_InitCore() didn't add.
3080
int
3081
_PySys_UpdateConfig(PyThreadState *tstate)
3082
{
3083
    PyInterpreterState *interp = tstate->interp;
3084
    PyObject *sysdict = interp->sysdict;
3085
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);
3086
    int res;
3087
3088
#define COPY_LIST(KEY, VALUE) \
3089
        SET_SYS(KEY, _PyWideStringList_AsList(&(VALUE)));
3090
3091
#define SET_SYS_FROM_WSTR(KEY, VALUE) \
3092
        SET_SYS(KEY, PyUnicode_FromWideChar(VALUE, -1));
3093
3094
#define COPY_WSTR(SYS_ATTR, WSTR) \
3095
    if (WSTR != NULL) { \
3096
        SET_SYS_FROM_WSTR(SYS_ATTR, WSTR); \
3097
    }
3098
3099
    if (config->module_search_paths_set) {
  Branch (3099:9): [True: 279, False: 1]
3100
        COPY_LIST("path", config->module_search_paths);
3101
    }
3102
3103
    COPY_WSTR("executable", config->executable);
3104
    COPY_WSTR("_base_executable", config->base_executable);
3105
    COPY_WSTR("prefix", config->prefix);
3106
    COPY_WSTR("base_prefix", config->base_prefix);
3107
    COPY_WSTR("exec_prefix", config->exec_prefix);
3108
    COPY_WSTR("base_exec_prefix", config->base_exec_prefix);
3109
    COPY_WSTR("platlibdir", config->platlibdir);
3110
3111
    if (config->pycache_prefix != NULL) {
  Branch (3111:9): [True: 3, False: 277]
3112
        SET_SYS_FROM_WSTR("pycache_prefix", config->pycache_prefix);
3113
    } else {
3114
        PyDict_SetItemString(sysdict, "pycache_prefix", Py_None);
3115
    }
3116
3117
    COPY_LIST("argv", config->argv);
3118
    COPY_LIST("orig_argv", config->orig_argv);
3119
    COPY_LIST("warnoptions", config->warnoptions);
3120
3121
    SET_SYS("_xoptions", sys_create_xoptions_dict(config));
3122
3123
    const wchar_t *stdlibdir = _Py_GetStdlibDir();
3124
    if (stdlibdir != NULL) {
  Branch (3124:9): [True: 278, False: 2]
3125
        SET_SYS_FROM_WSTR("_stdlib_dir", stdlibdir);
3126
    }
3127
    else {
3128
        PyDict_SetItemString(sysdict, "_stdlib_dir", Py_None);
3129
    }
3130
3131
#undef SET_SYS_FROM_WSTR
3132
#undef COPY_LIST
3133
#undef COPY_WSTR
3134
3135
    // sys.flags
3136
    PyObject *flags = _PySys_GetObject(interp, "flags"); // borrowed ref
3137
    if (flags == NULL) {
  Branch (3137:9): [True: 0, False: 280]
3138
        return -1;
3139
    }
3140
    if (set_flags_from_config(interp, flags) < 0) {
  Branch (3140:9): [True: 0, False: 280]
3141
        return -1;
3142
    }
3143
3144
    SET_SYS("dont_write_bytecode", PyBool_FromLong(!config->write_bytecode));
3145
3146
    if (_PyErr_Occurred(tstate)) {
  Branch (3146:9): [True: 0, False: 280]
3147
        goto err_occurred;
3148
    }
3149
3150
    return 0;
3151
3152
err_occurred:
3153
    return -1;
3154
}
3155
3156
#undef SET_SYS
3157
#undef SET_SYS_FROM_STRING
3158
3159
3160
/* Set up a preliminary stderr printer until we have enough
3161
   infrastructure for the io module in place.
3162
3163
   Use UTF-8/backslashreplace and ignore EAGAIN errors. */
3164
static PyStatus
3165
_PySys_SetPreliminaryStderr(PyObject *sysdict)
3166
{
3167
    PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr));
3168
    if (pstderr == NULL) {
  Branch (3168:9): [True: 0, False: 278]
3169
        goto error;
3170
    }
3171
    if (PyDict_SetItem(sysdict, &_Py_ID(stderr), pstderr) < 0) {
  Branch (3171:9): [True: 0, False: 278]
3172
        goto error;
3173
    }
3174
    if (PyDict_SetItemString(sysdict, "__stderr__", pstderr) < 0) {
  Branch (3174:9): [True: 0, False: 278]
3175
        goto error;
3176
    }
3177
    Py_DECREF(pstderr);
3178
    return _PyStatus_OK();
3179
3180
error:
3181
    Py_XDECREF(pstderr);
3182
    return _PyStatus_ERR("can't set preliminary stderr");
3183
}
3184
3185
3186
/* Create sys module without all attributes.
3187
   _PySys_UpdateConfig() should be called later to add remaining attributes. */
3188
PyStatus
3189
_PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
3190
{
3191
    assert(!_PyErr_Occurred(tstate));
3192
3193
    PyInterpreterState *interp = tstate->interp;
3194
3195
    PyObject *modules = PyDict_New();
3196
    if (modules == NULL) {
  Branch (3196:9): [True: 0, False: 278]
3197
        goto error;
3198
    }
3199
    interp->modules = modules;
3200
3201
    PyObject *sysmod = _PyModule_CreateInitialized(&sysmodule, PYTHON_API_VERSION);
3202
    if (sysmod == NULL) {
  Branch (3202:9): [True: 0, False: 278]
3203
        return _PyStatus_ERR("failed to create a module object");
3204
    }
3205
3206
    PyObject *sysdict = PyModule_GetDict(sysmod);
3207
    if (sysdict == NULL) {
  Branch (3207:9): [True: 0, False: 278]
3208
        goto error;
3209
    }
3210
    Py_INCREF(sysdict);
3211
    interp->sysdict = sysdict;
3212
3213
    if (PyDict_SetItemString(sysdict, "modules", interp->modules) < 0) {
  Branch (3213:9): [True: 0, False: 278]
3214
        goto error;
3215
    }
3216
3217
    PyStatus status = _PySys_SetPreliminaryStderr(sysdict);
3218
    if (_PyStatus_EXCEPTION(status)) {
3219
        return status;
3220
    }
3221
3222
    status = _PySys_InitCore(tstate, sysdict);
3223
    if (_PyStatus_EXCEPTION(status)) {
3224
        return status;
3225
    }
3226
3227
    if (_PyImport_FixupBuiltin(sysmod, "sys", interp->modules) < 0) {
  Branch (3227:9): [True: 0, False: 278]
3228
        goto error;
3229
    }
3230
3231
    assert(!_PyErr_Occurred(tstate));
3232
3233
    *sysmod_p = sysmod;
3234
    return _PyStatus_OK();
3235
3236
error:
3237
    return _PyStatus_ERR("can't initialize sys module");
3238
}
3239
3240
3241
void
3242
_PySys_Fini(PyInterpreterState *interp)
3243
{
3244
    if (_Py_IsMainInterpreter(interp)) {
  Branch (3244:9): [True: 103, False: 169]
3245
        _PyStructSequence_FiniType(&VersionInfoType);
3246
        _PyStructSequence_FiniType(&FlagsType);
3247
#if defined(MS_WINDOWS)
3248
        _PyStructSequence_FiniType(&WindowsVersionType);
3249
#endif
3250
        _PyStructSequence_FiniType(&Hash_InfoType);
3251
        _PyStructSequence_FiniType(&AsyncGenHooksType);
3252
#ifdef __EMSCRIPTEN__
3253
        Py_CLEAR(EmscriptenInfoType);
3254
#endif
3255
    }
3256
}
3257
3258
3259
static PyObject *
3260
makepathobject(const wchar_t *path, wchar_t delim)
3261
{
3262
    int i, n;
3263
    const wchar_t *p;
3264
    PyObject *v, *w;
3265
3266
    n = 1;
3267
    p = path;
3268
    while ((p = wcschr(p, delim)) != NULL) {
  Branch (3268:12): [True: 0, False: 0]
3269
        n++;
3270
        p++;
3271
    }
3272
    v = PyList_New(n);
3273
    if (v == NULL)
  Branch (3273:9): [True: 0, False: 0]
3274
        return NULL;
3275
    for (i = 0; ; i++) {
3276
        p = wcschr(path, delim);
3277
        if (p == NULL)
  Branch (3277:13): [True: 0, False: 0]
3278
            p = path + wcslen(path); /* End of string */
3279
        w = PyUnicode_FromWideChar(path, (Py_ssize_t)(p - path));
3280
        if (w == NULL) {
  Branch (3280:13): [True: 0, False: 0]
3281
            Py_DECREF(v);
3282
            return NULL;
3283
        }
3284
        PyList_SET_ITEM(v, i, w);
3285
        if (*p == '\0')
  Branch (3285:13): [True: 0, False: 0]
3286
            break;
3287
        path = p+1;
3288
    }
3289
    return v;
3290
}
3291
3292
void
3293
PySys_SetPath(const wchar_t *path)
3294
{
3295
    PyObject *v;
3296
    if ((v = makepathobject(path, DELIM)) == NULL)
  Branch (3296:9): [True: 0, False: 0]
3297
        Py_FatalError("can't create sys.path");
3298
    PyInterpreterState *interp = _PyInterpreterState_GET();
3299
    if (sys_set_object(interp, &_Py_ID(path), v) != 0) {
  Branch (3299:9): [True: 0, False: 0]
3300
        Py_FatalError("can't assign sys.path");
3301
    }
3302
    Py_DECREF(v);
3303
}
3304
3305
static PyObject *
3306
make_sys_argv(int argc, wchar_t * const * argv)
3307
{
3308
    PyObject *list = PyList_New(argc);
3309
    if (list == NULL) {
  Branch (3309:9): [True: 0, False: 0]
3310
        return NULL;
3311
    }
3312
3313
    for (Py_ssize_t i = 0; i < argc; i++) {
  Branch (3313:28): [True: 0, False: 0]
3314
        PyObject *v = PyUnicode_FromWideChar(argv[i], -1);
3315
        if (v == NULL) {
  Branch (3315:13): [True: 0, False: 0]
3316
            Py_DECREF(list);
3317
            return NULL;
3318
        }
3319
        PyList_SET_ITEM(list, i, v);
3320
    }
3321
    return list;
3322
}
3323
3324
void
3325
PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
3326
{
3327
    wchar_t* empty_argv[1] = {L""};
3328
    PyThreadState *tstate = _PyThreadState_GET();
3329
3330
    if (argc < 1 || argv == NULL) {
  Branch (3330:9): [True: 0, False: 0]
  Branch (3330:21): [True: 0, False: 0]
3331
        /* Ensure at least one (empty) argument is seen */
3332
        argv = empty_argv;
3333
        argc = 1;
3334
    }
3335
3336
    PyObject *av = make_sys_argv(argc, argv);
3337
    if (av == NULL) {
  Branch (3337:9): [True: 0, False: 0]
3338
        Py_FatalError("no mem for sys.argv");
3339
    }
3340
    if (sys_set_object_str(tstate->interp, "argv", av) != 0) {
  Branch (3340:9): [True: 0, False: 0]
3341
        Py_DECREF(av);
3342
        Py_FatalError("can't assign sys.argv");
3343
    }
3344
    Py_DECREF(av);
3345
3346
    if (updatepath) {
  Branch (3346:9): [True: 0, False: 0]
3347
        /* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path.
3348
           If argv[0] is a symlink, use the real path. */
3349
        const PyWideStringList argv_list = {.length = argc, .items = argv};
3350
        PyObject *path0 = NULL;
3351
        if (_PyPathConfig_ComputeSysPath0(&argv_list, &path0)) {
  Branch (3351:13): [True: 0, False: 0]
3352
            if (path0 == NULL) {
  Branch (3352:17): [True: 0, False: 0]
3353
                Py_FatalError("can't compute path0 from argv");
3354
            }
3355
3356
            PyObject *sys_path = _PySys_GetAttr(tstate, &_Py_ID(path));
3357
            if (sys_path != NULL) {
  Branch (3357:17): [True: 0, False: 0]
3358
                if (PyList_Insert(sys_path, 0, path0) < 0) {
  Branch (3358:21): [True: 0, False: 0]
3359
                    Py_DECREF(path0);
3360
                    Py_FatalError("can't prepend path0 to sys.path");
3361
                }
3362
            }
3363
            Py_DECREF(path0);
3364
        }
3365
    }
3366
}
3367
3368
void
3369
PySys_SetArgv(int argc, wchar_t **argv)
3370
{
3371
_Py_COMP_DIAG_PUSH
3372
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
3373
    PySys_SetArgvEx(argc, argv, Py_IsolatedFlag == 0);
3374
_Py_COMP_DIAG_POP
3375
}
3376
3377
/* Reimplementation of PyFile_WriteString() no calling indirectly
3378
   PyErr_CheckSignals(): avoid the call to PyObject_Str(). */
3379
3380
static int
3381
sys_pyfile_write_unicode(PyObject *unicode, PyObject *file)
3382
{
3383
    if (file == NULL)
  Branch (3383:9): [True: 0, False: 579]
3384
        return -1;
3385
    assert(unicode != NULL);
3386
    PyObject *result = _PyObject_CallMethodOneArg(file, &_Py_ID(write), unicode);
3387
    if (result == NULL) {
  Branch (3387:9): [True: 71, False: 508]
3388
        return -1;
3389
    }
3390
    Py_DECREF(result);
3391
    return 0;
3392
}
3393
3394
static int
3395
sys_pyfile_write(const char *text, PyObject *file)
3396
{
3397
    PyObject *unicode = NULL;
3398
    int err;
3399
3400
    if (file == NULL)
  Branch (3400:9): [True: 4, False: 68]
3401
        return -1;
3402
3403
    unicode = PyUnicode_FromString(text);
3404
    if (unicode == NULL)
  Branch (3404:9): [True: 0, False: 68]
3405
        return -1;
3406
3407
    err = sys_pyfile_write_unicode(unicode, file);
3408
    Py_DECREF(unicode);
3409
    return err;
3410
}
3411
3412
/* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
3413
   Adapted from code submitted by Just van Rossum.
3414
3415
   PySys_WriteStdout(format, ...)
3416
   PySys_WriteStderr(format, ...)
3417
3418
      The first function writes to sys.stdout; the second to sys.stderr.  When
3419
      there is a problem, they write to the real (C level) stdout or stderr;
3420
      no exceptions are raised.
3421
3422
      PyErr_CheckSignals() is not called to avoid the execution of the Python
3423
      signal handlers: they may raise a new exception whereas sys_write()
3424
      ignores all exceptions.
3425
3426
      Both take a printf-style format string as their first argument followed
3427
      by a variable length argument list determined by the format string.
3428
3429
      *** WARNING ***
3430
3431
      The format should limit the total size of the formatted output string to
3432
      1000 bytes.  In particular, this means that no unrestricted "%s" formats
3433
      should occur; these should be limited using "%.<N>s where <N> is a
3434
      decimal number calculated so that <N> plus the maximum size of other
3435
      formatted text does not exceed 1000 bytes.  Also watch out for "%f",
3436
      which can print hundreds of digits for very large numbers.
3437
3438
 */
3439
3440
static void
3441
sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
3442
{
3443
    PyObject *file;
3444
    PyObject *error_type, *error_value, *error_traceback;
3445
    char buffer[1001];
3446
    int written;
3447
    PyThreadState *tstate = _PyThreadState_GET();
3448
3449
    _PyErr_Fetch(tstate, &error_type, &error_value, &error_traceback);
3450
    file = _PySys_GetAttr(tstate, key);
3451
    written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
3452
    if (sys_pyfile_write(buffer, file) != 0) {
  Branch (3452:9): [True: 4, False: 68]
3453
        _PyErr_Clear(tstate);
3454
        fputs(buffer, fp);
3455
    }
3456
    if (written < 0 || (size_t)written >= sizeof(buffer)) {
  Branch (3456:9): [True: 0, False: 72]
  Branch (3456:24): [True: 0, False: 72]
3457
        const char *truncated = "... truncated";
3458
        if (sys_pyfile_write(truncated, file) != 0)
  Branch (3458:13): [True: 0, False: 0]
3459
            fputs(truncated, fp);
3460
    }
3461
    _PyErr_Restore(tstate, error_type, error_value, error_traceback);
3462
}
3463
3464
void
3465
PySys_WriteStdout(const char *format, ...)
3466
{
3467
    va_list va;
3468
3469
    va_start(va, format);
3470
    sys_write(&_Py_ID(stdout), stdout, format, va);
3471
    va_end(va);
3472
}
3473
3474
void
3475
PySys_WriteStderr(const char *format, ...)
3476
{
3477
    va_list va;
3478
3479
    va_start(va, format);
3480
    sys_write(&_Py_ID(stderr), stderr, format, va);
3481
    va_end(va);
3482
}
3483
3484
static void
3485
sys_format(PyObject *key, FILE *fp, const char *format, va_list va)
3486
{
3487
    PyObject *file, *message;
3488
    PyObject *error_type, *error_value, *error_traceback;
3489
    const char *utf8;
3490
    PyThreadState *tstate = _PyThreadState_GET();
3491
3492
    _PyErr_Fetch(tstate, &error_type, &error_value, &error_traceback);
3493
    file = _PySys_GetAttr(tstate, key);
3494
    message = PyUnicode_FromFormatV(format, va);
3495
    if (message != NULL) {
  Branch (3495:9): [True: 511, False: 0]
3496
        if (sys_pyfile_write_unicode(message, file) != 0) {
  Branch (3496:13): [True: 71, False: 440]
3497
            _PyErr_Clear(tstate);
3498
            utf8 = PyUnicode_AsUTF8(message);
3499
            if (utf8 != NULL)
  Branch (3499:17): [True: 71, False: 0]
3500
                fputs(utf8, fp);
3501
        }
3502
        Py_DECREF(message);
3503
    }
3504
    _PyErr_Restore(tstate, error_type, error_value, error_traceback);
3505
}
3506
3507
void
3508
PySys_FormatStdout(const char *format, ...)
3509
{
3510
    va_list va;
3511
3512
    va_start(va, format);
3513
    sys_format(&_Py_ID(stdout), stdout, format, va);
3514
    va_end(va);
3515
}
3516
3517
void
3518
PySys_FormatStderr(const char *format, ...)
3519
{
3520
    va_list va;
3521
3522
    va_start(va, format);
3523
    sys_format(&_Py_ID(stderr), stderr, format, va);
3524
    va_end(va);
3525
}