Coverage Report

Created: 2025-07-11 06:59

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