1
2/* System module */
3
4/*
5Various bits of information used by the interpreter are collected in
6module 'sys'.
7Function member:
8- exit(sts): raise SystemExit
9Data 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 "pythread.h"
21
22#include "osdefs.h"
23#include <locale.h>
24
25#ifdef MS_WINDOWS
26#define WIN32_LEAN_AND_MEAN
27#include <windows.h>
28#endif /* MS_WINDOWS */
29
30#ifdef MS_COREDLL
31extern void *PyWin_DLLhModule;
32/* A string loaded from the DLL at startup: */
33extern const char *PyWin_DLLVersionString;
34#endif
35
36#ifdef HAVE_LANGINFO_H
37#include <langinfo.h>
38#endif
39
40_Py_IDENTIFIER(_);
41_Py_IDENTIFIER(__sizeof__);
42_Py_IDENTIFIER(buffer);
43_Py_IDENTIFIER(builtins);
44_Py_IDENTIFIER(encoding);
45_Py_IDENTIFIER(path);
46_Py_IDENTIFIER(stdout);
47_Py_IDENTIFIER(stderr);
48_Py_IDENTIFIER(write);
49
50PyObject *
51_PySys_GetObjectId(_Py_Identifier *key)
52{
53    PyThreadState *tstate = PyThreadState_GET();
54    PyObject *sd = tstate->interp->sysdict;
55    if (sd == NULL)
56        return NULL;
57    return _PyDict_GetItemId(sd, key);
58}
59
60PyObject *
61PySys_GetObject(const char *name)
62{
63    PyThreadState *tstate = PyThreadState_GET();
64    PyObject *sd = tstate->interp->sysdict;
65    if (sd == NULL)
66        return NULL;
67    return PyDict_GetItemString(sd, name);
68}
69
70int
71_PySys_SetObjectId(_Py_Identifier *key, PyObject *v)
72{
73    PyThreadState *tstate = PyThreadState_GET();
74    PyObject *sd = tstate->interp->sysdict;
75    if (v == NULL) {
76        if (_PyDict_GetItemId(sd, key) == NULL)
77            return 0;
78        else
79            return _PyDict_DelItemId(sd, key);
80    }
81    else
82        return _PyDict_SetItemId(sd, key, v);
83}
84
85int
86PySys_SetObject(const char *name, PyObject *v)
87{
88    PyThreadState *tstate = PyThreadState_GET();
89    PyObject *sd = tstate->interp->sysdict;
90    if (v == NULL) {
91        if (PyDict_GetItemString(sd, name) == NULL)
92            return 0;
93        else
94            return PyDict_DelItemString(sd, name);
95    }
96    else
97        return PyDict_SetItemString(sd, name, v);
98}
99
100/* Write repr(o) to sys.stdout using sys.stdout.encoding and 'backslashreplace'
101   error handler. If sys.stdout has a buffer attribute, use
102   sys.stdout.buffer.write(encoded), otherwise redecode the string and use
103   sys.stdout.write(redecoded).
104
105   Helper function for sys_displayhook(). */
106static int
107sys_displayhook_unencodable(PyObject *outf, PyObject *o)
108{
109    PyObject *stdout_encoding = NULL;
110    PyObject *encoded, *escaped_str, *repr_str, *buffer, *result;
111    char *stdout_encoding_str;
112    int ret;
113
114    stdout_encoding = _PyObject_GetAttrId(outf, &PyId_encoding);
115    if (stdout_encoding == NULL)
116        goto error;
117    stdout_encoding_str = PyUnicode_AsUTF8(stdout_encoding);
118    if (stdout_encoding_str == NULL)
119        goto error;
120
121    repr_str = PyObject_Repr(o);
122    if (repr_str == NULL)
123        goto error;
124    encoded = PyUnicode_AsEncodedString(repr_str,
125                                        stdout_encoding_str,
126                                        "backslashreplace");
127    Py_DECREF(repr_str);
128    if (encoded == NULL)
129        goto error;
130
131    buffer = _PyObject_GetAttrId(outf, &PyId_buffer);
132    if (buffer) {
133        result = _PyObject_CallMethodId(buffer, &PyId_write, "(O)", encoded);
134        Py_DECREF(buffer);
135        Py_DECREF(encoded);
136        if (result == NULL)
137            goto error;
138        Py_DECREF(result);
139    }
140    else {
141        PyErr_Clear();
142        escaped_str = PyUnicode_FromEncodedObject(encoded,
143                                                  stdout_encoding_str,
144                                                  "strict");
145        Py_DECREF(encoded);
146        if (PyFile_WriteObject(escaped_str, outf, Py_PRINT_RAW) != 0) {
147            Py_DECREF(escaped_str);
148            goto error;
149        }
150        Py_DECREF(escaped_str);
151    }
152    ret = 0;
153    goto finally;
154
155error:
156    ret = -1;
157finally:
158    Py_XDECREF(stdout_encoding);
159    return ret;
160}
161
162static PyObject *
163sys_displayhook(PyObject *self, PyObject *o)
164{
165    PyObject *outf;
166    PyInterpreterState *interp = PyThreadState_GET()->interp;
167    PyObject *modules = interp->modules;
168    PyObject *builtins;
169    static PyObject *newline = NULL;
170    int err;
171
172    builtins = _PyDict_GetItemId(modules, &PyId_builtins);
173    if (builtins == NULL) {
174        PyErr_SetString(PyExc_RuntimeError, "lost builtins module");
175        return NULL;
176    }
177
178    /* Print value except if None */
179    /* After printing, also assign to '_' */
180    /* Before, set '_' to None to avoid recursion */
181    if (o == Py_None) {
182        Py_INCREF(Py_None);
183        return Py_None;
184    }
185    if (_PyObject_SetAttrId(builtins, &PyId__, Py_None) != 0)
186        return NULL;
187    outf = _PySys_GetObjectId(&PyId_stdout);
188    if (outf == NULL || outf == Py_None) {
189        PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
190        return NULL;
191    }
192    if (PyFile_WriteObject(o, outf, 0) != 0) {
193        if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
194            /* repr(o) is not encodable to sys.stdout.encoding with
195             * sys.stdout.errors error handler (which is probably 'strict') */
196            PyErr_Clear();
197            err = sys_displayhook_unencodable(outf, o);
198            if (err)
199                return NULL;
200        }
201        else {
202            return NULL;
203        }
204    }
205    if (newline == NULL) {
206        newline = PyUnicode_FromString("\n");
207        if (newline == NULL)
208            return NULL;
209    }
210    if (PyFile_WriteObject(newline, outf, Py_PRINT_RAW) != 0)
211        return NULL;
212    if (_PyObject_SetAttrId(builtins, &PyId__, o) != 0)
213        return NULL;
214    Py_INCREF(Py_None);
215    return Py_None;
216}
217
218PyDoc_STRVAR(displayhook_doc,
219"displayhook(object) -> None\n"
220"\n"
221"Print an object to sys.stdout and also save it in builtins._\n"
222);
223
224static PyObject *
225sys_excepthook(PyObject* self, PyObject* args)
226{
227    PyObject *exc, *value, *tb;
228    if (!PyArg_UnpackTuple(args, "excepthook", 3, 3, &exc, &value, &tb))
229        return NULL;
230    PyErr_Display(exc, value, tb);
231    Py_INCREF(Py_None);
232    return Py_None;
233}
234
235PyDoc_STRVAR(excepthook_doc,
236"excepthook(exctype, value, traceback) -> None\n"
237"\n"
238"Handle an exception by displaying it with a traceback on sys.stderr.\n"
239);
240
241static PyObject *
242sys_exc_info(PyObject *self, PyObject *noargs)
243{
244    PyThreadState *tstate;
245    tstate = PyThreadState_GET();
246    return Py_BuildValue(
247        "(OOO)",
248        tstate->exc_type != NULL ? tstate->exc_type : Py_None,
249        tstate->exc_value != NULL ? tstate->exc_value : Py_None,
250        tstate->exc_traceback != NULL ?
251            tstate->exc_traceback : Py_None);
252}
253
254PyDoc_STRVAR(exc_info_doc,
255"exc_info() -> (type, value, traceback)\n\
256\n\
257Return information about the most recent exception caught by an except\n\
258clause in the current stack frame or in an older stack frame."
259);
260
261static PyObject *
262sys_exit(PyObject *self, PyObject *args)
263{
264    PyObject *exit_code = 0;
265    if (!PyArg_UnpackTuple(args, "exit", 0, 1, &exit_code))
266        return NULL;
267    /* Raise SystemExit so callers may catch it or clean up. */
268    PyErr_SetObject(PyExc_SystemExit, exit_code);
269    return NULL;
270}
271
272PyDoc_STRVAR(exit_doc,
273"exit([status])\n\
274\n\
275Exit the interpreter by raising SystemExit(status).\n\
276If the status is omitted or None, it defaults to zero (i.e., success).\n\
277If the status is an integer, it will be used as the system exit status.\n\
278If it is another kind of object, it will be printed and the system\n\
279exit status will be one (i.e., failure)."
280);
281
282
283static PyObject *
284sys_getdefaultencoding(PyObject *self)
285{
286    return PyUnicode_FromString(PyUnicode_GetDefaultEncoding());
287}
288
289PyDoc_STRVAR(getdefaultencoding_doc,
290"getdefaultencoding() -> string\n\
291\n\
292Return the current default string encoding used by the Unicode \n\
293implementation."
294);
295
296static PyObject *
297sys_getfilesystemencoding(PyObject *self)
298{
299    if (Py_FileSystemDefaultEncoding)
300        return PyUnicode_FromString(Py_FileSystemDefaultEncoding);
301    PyErr_SetString(PyExc_RuntimeError,
302                    "filesystem encoding is not initialized");
303    return NULL;
304}
305
306PyDoc_STRVAR(getfilesystemencoding_doc,
307"getfilesystemencoding() -> string\n\
308\n\
309Return the encoding used to convert Unicode filenames in\n\
310operating system filenames."
311);
312
313static PyObject *
314sys_getfilesystemencodeerrors(PyObject *self)
315{
316    if (Py_FileSystemDefaultEncodeErrors)
317        return PyUnicode_FromString(Py_FileSystemDefaultEncodeErrors);
318    PyErr_SetString(PyExc_RuntimeError,
319        "filesystem encoding is not initialized");
320    return NULL;
321}
322
323PyDoc_STRVAR(getfilesystemencodeerrors_doc,
324    "getfilesystemencodeerrors() -> string\n\
325\n\
326Return the error mode used to convert Unicode filenames in\n\
327operating system filenames."
328);
329
330static PyObject *
331sys_intern(PyObject *self, PyObject *args)
332{
333    PyObject *s;
334    if (!PyArg_ParseTuple(args, "U:intern", &s))
335        return NULL;
336    if (PyUnicode_CheckExact(s)) {
337        Py_INCREF(s);
338        PyUnicode_InternInPlace(&s);
339        return s;
340    }
341    else {
342        PyErr_Format(PyExc_TypeError,
343                        "can't intern %.400s", s->ob_type->tp_name);
344        return NULL;
345    }
346}
347
348PyDoc_STRVAR(intern_doc,
349"intern(string) -> string\n\
350\n\
351``Intern'' the given string.  This enters the string in the (global)\n\
352table of interned strings whose purpose is to speed up dictionary lookups.\n\
353Return the string itself or the previously interned string object with the\n\
354same value.");
355
356
357/*
358 * Cached interned string objects used for calling the profile and
359 * trace functions.  Initialized by trace_init().
360 */
361static PyObject *whatstrings[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
362
363static int
364trace_init(void)
365{
366    static const char * const whatnames[7] = {
367        "call", "exception", "line", "return",
368        "c_call", "c_exception", "c_return"
369    };
370    PyObject *name;
371    int i;
372    for (i = 0; i < 7; ++i) {
373        if (whatstrings[i] == NULL) {
374            name = PyUnicode_InternFromString(whatnames[i]);
375            if (name == NULL)
376                return -1;
377            whatstrings[i] = name;
378        }
379    }
380    return 0;
381}
382
383
384static PyObject *
385call_trampoline(PyObject* callback,
386                PyFrameObject *frame, int what, PyObject *arg)
387{
388    PyObject *result;
389    PyObject *stack[3];
390
391    if (PyFrame_FastToLocalsWithError(frame) < 0) {
392        return NULL;
393    }
394
395    stack[0] = (PyObject *)frame;
396    stack[1] = whatstrings[what];
397    stack[2] = (arg != NULL) ? arg : Py_None;
398
399    /* call the Python-level function */
400    result = _PyObject_FastCall(callback, stack, 3);
401
402    PyFrame_LocalsToFast(frame, 1);
403    if (result == NULL) {
404        PyTraceBack_Here(frame);
405    }
406
407    return result;
408}
409
410static int
411profile_trampoline(PyObject *self, PyFrameObject *frame,
412                   int what, PyObject *arg)
413{
414    PyObject *result;
415
416    if (arg == NULL)
417        arg = Py_None;
418    result = call_trampoline(self, frame, what, arg);
419    if (result == NULL) {
420        PyEval_SetProfile(NULL, NULL);
421        return -1;
422    }
423    Py_DECREF(result);
424    return 0;
425}
426
427static int
428trace_trampoline(PyObject *self, PyFrameObject *frame,
429                 int what, PyObject *arg)
430{
431    PyObject *callback;
432    PyObject *result;
433
434    if (what == PyTrace_CALL)
435        callback = self;
436    else
437        callback = frame->f_trace;
438    if (callback == NULL)
439        return 0;
440    result = call_trampoline(callback, frame, what, arg);
441    if (result == NULL) {
442        PyEval_SetTrace(NULL, NULL);
443        Py_CLEAR(frame->f_trace);
444        return -1;
445    }
446    if (result != Py_None) {
447        Py_XSETREF(frame->f_trace, result);
448    }
449    else {
450        Py_DECREF(result);
451    }
452    return 0;
453}
454
455static PyObject *
456sys_settrace(PyObject *self, PyObject *args)
457{
458    if (trace_init() == -1)
459        return NULL;
460    if (args == Py_None)
461        PyEval_SetTrace(NULL, NULL);
462    else
463        PyEval_SetTrace(trace_trampoline, args);
464    Py_INCREF(Py_None);
465    return Py_None;
466}
467
468PyDoc_STRVAR(settrace_doc,
469"settrace(function)\n\
470\n\
471Set the global debug tracing function.  It will be called on each\n\
472function call.  See the debugger chapter in the library manual."
473);
474
475static PyObject *
476sys_gettrace(PyObject *self, PyObject *args)
477{
478    PyThreadState *tstate = PyThreadState_GET();
479    PyObject *temp = tstate->c_traceobj;
480
481    if (temp == NULL)
482        temp = Py_None;
483    Py_INCREF(temp);
484    return temp;
485}
486
487PyDoc_STRVAR(gettrace_doc,
488"gettrace()\n\
489\n\
490Return the global debug tracing function set with sys.settrace.\n\
491See the debugger chapter in the library manual."
492);
493
494static PyObject *
495sys_setprofile(PyObject *self, PyObject *args)
496{
497    if (trace_init() == -1)
498        return NULL;
499    if (args == Py_None)
500        PyEval_SetProfile(NULL, NULL);
501    else
502        PyEval_SetProfile(profile_trampoline, args);
503    Py_INCREF(Py_None);
504    return Py_None;
505}
506
507PyDoc_STRVAR(setprofile_doc,
508"setprofile(function)\n\
509\n\
510Set the profiling function.  It will be called on each function call\n\
511and return.  See the profiler chapter in the library manual."
512);
513
514static PyObject *
515sys_getprofile(PyObject *self, PyObject *args)
516{
517    PyThreadState *tstate = PyThreadState_GET();
518    PyObject *temp = tstate->c_profileobj;
519
520    if (temp == NULL)
521        temp = Py_None;
522    Py_INCREF(temp);
523    return temp;
524}
525
526PyDoc_STRVAR(getprofile_doc,
527"getprofile()\n\
528\n\
529Return the profiling function set with sys.setprofile.\n\
530See the profiler chapter in the library manual."
531);
532
533static int _check_interval = 100;
534
535static PyObject *
536sys_setcheckinterval(PyObject *self, PyObject *args)
537{
538    if (PyErr_WarnEx(PyExc_DeprecationWarning,
539                     "sys.getcheckinterval() and sys.setcheckinterval() "
540                     "are deprecated.  Use sys.setswitchinterval() "
541                     "instead.", 1) < 0)
542        return NULL;
543    if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_check_interval))
544        return NULL;
545    Py_INCREF(Py_None);
546    return Py_None;
547}
548
549PyDoc_STRVAR(setcheckinterval_doc,
550"setcheckinterval(n)\n\
551\n\
552Tell the Python interpreter to check for asynchronous events every\n\
553n instructions.  This also affects how often thread switches occur."
554);
555
556static PyObject *
557sys_getcheckinterval(PyObject *self, PyObject *args)
558{
559    if (PyErr_WarnEx(PyExc_DeprecationWarning,
560                     "sys.getcheckinterval() and sys.setcheckinterval() "
561                     "are deprecated.  Use sys.getswitchinterval() "
562                     "instead.", 1) < 0)
563        return NULL;
564    return PyLong_FromLong(_check_interval);
565}
566
567PyDoc_STRVAR(getcheckinterval_doc,
568"getcheckinterval() -> current check interval; see setcheckinterval()."
569);
570
571#ifdef WITH_THREAD
572static PyObject *
573sys_setswitchinterval(PyObject *self, PyObject *args)
574{
575    double d;
576    if (!PyArg_ParseTuple(args, "d:setswitchinterval", &d))
577        return NULL;
578    if (d <= 0.0) {
579        PyErr_SetString(PyExc_ValueError,
580                        "switch interval must be strictly positive");
581        return NULL;
582    }
583    _PyEval_SetSwitchInterval((unsigned long) (1e6 * d));
584    Py_INCREF(Py_None);
585    return Py_None;
586}
587
588PyDoc_STRVAR(setswitchinterval_doc,
589"setswitchinterval(n)\n\
590\n\
591Set the ideal thread switching delay inside the Python interpreter\n\
592The actual frequency of switching threads can be lower if the\n\
593interpreter executes long sequences of uninterruptible code\n\
594(this is implementation-specific and workload-dependent).\n\
595\n\
596The parameter must represent the desired switching delay in seconds\n\
597A typical value is 0.005 (5 milliseconds)."
598);
599
600static PyObject *
601sys_getswitchinterval(PyObject *self, PyObject *args)
602{
603    return PyFloat_FromDouble(1e-6 * _PyEval_GetSwitchInterval());
604}
605
606PyDoc_STRVAR(getswitchinterval_doc,
607"getswitchinterval() -> current thread switch interval; see setswitchinterval()."
608);
609
610#endif /* WITH_THREAD */
611
612static PyObject *
613sys_setrecursionlimit(PyObject *self, PyObject *args)
614{
615    int new_limit, mark;
616    PyThreadState *tstate;
617
618    if (!PyArg_ParseTuple(args, "i:setrecursionlimit", &new_limit))
619        return NULL;
620
621    if (new_limit < 1) {
622        PyErr_SetString(PyExc_ValueError,
623                        "recursion limit must be greater or equal than 1");
624        return NULL;
625    }
626
627    /* Issue #25274: When the recursion depth hits the recursion limit in
628       _Py_CheckRecursiveCall(), the overflowed flag of the thread state is
629       set to 1 and a RecursionError is raised. The overflowed flag is reset
630       to 0 when the recursion depth goes below the low-water mark: see
631       Py_LeaveRecursiveCall().
632
633       Reject too low new limit if the current recursion depth is higher than
634       the new low-water mark. Otherwise it may not be possible anymore to
635       reset the overflowed flag to 0. */
636    mark = _Py_RecursionLimitLowerWaterMark(new_limit);
637    tstate = PyThreadState_GET();
638    if (tstate->recursion_depth >= mark) {
639        PyErr_Format(PyExc_RecursionError,
640                     "cannot set the recursion limit to %i at "
641                     "the recursion depth %i: the limit is too low",
642                     new_limit, tstate->recursion_depth);
643        return NULL;
644    }
645
646    Py_SetRecursionLimit(new_limit);
647    Py_INCREF(Py_None);
648    return Py_None;
649}
650
651static PyObject *
652sys_set_coroutine_wrapper(PyObject *self, PyObject *wrapper)
653{
654    if (wrapper != Py_None) {
655        if (!PyCallable_Check(wrapper)) {
656            PyErr_Format(PyExc_TypeError,
657                         "callable expected, got %.50s",
658                         Py_TYPE(wrapper)->tp_name);
659            return NULL;
660        }
661        _PyEval_SetCoroutineWrapper(wrapper);
662    }
663    else {
664        _PyEval_SetCoroutineWrapper(NULL);
665    }
666    Py_RETURN_NONE;
667}
668
669PyDoc_STRVAR(set_coroutine_wrapper_doc,
670"set_coroutine_wrapper(wrapper)\n\
671\n\
672Set a wrapper for coroutine objects."
673);
674
675static PyObject *
676sys_get_coroutine_wrapper(PyObject *self, PyObject *args)
677{
678    PyObject *wrapper = _PyEval_GetCoroutineWrapper();
679    if (wrapper == NULL) {
680        wrapper = Py_None;
681    }
682    Py_INCREF(wrapper);
683    return wrapper;
684}
685
686PyDoc_STRVAR(get_coroutine_wrapper_doc,
687"get_coroutine_wrapper()\n\
688\n\
689Return the wrapper for coroutine objects set by sys.set_coroutine_wrapper."
690);
691
692
693static PyTypeObject AsyncGenHooksType;
694
695PyDoc_STRVAR(asyncgen_hooks_doc,
696"asyncgen_hooks\n\
697\n\
698A struct sequence providing information about asynhronous\n\
699generators hooks.  The attributes are read only.");
700
701static PyStructSequence_Field asyncgen_hooks_fields[] = {
702    {"firstiter", "Hook to intercept first iteration"},
703    {"finalizer", "Hook to intercept finalization"},
704    {0}
705};
706
707static PyStructSequence_Desc asyncgen_hooks_desc = {
708    "asyncgen_hooks",          /* name */
709    asyncgen_hooks_doc,        /* doc */
710    asyncgen_hooks_fields ,    /* fields */
711    2
712};
713
714
715static PyObject *
716sys_set_asyncgen_hooks(PyObject *self, PyObject *args, PyObject *kw)
717{
718    static char *keywords[] = {"firstiter", "finalizer", NULL};
719    PyObject *firstiter = NULL;
720    PyObject *finalizer = NULL;
721
722    if (!PyArg_ParseTupleAndKeywords(
723            args, kw, "|OO", keywords,
724            &firstiter, &finalizer)) {
725        return NULL;
726    }
727
728    if (finalizer && finalizer != Py_None) {
729        if (!PyCallable_Check(finalizer)) {
730            PyErr_Format(PyExc_TypeError,
731                         "callable finalizer expected, got %.50s",
732                         Py_TYPE(finalizer)->tp_name);
733            return NULL;
734        }
735        _PyEval_SetAsyncGenFinalizer(finalizer);
736    }
737    else if (finalizer == Py_None) {
738        _PyEval_SetAsyncGenFinalizer(NULL);
739    }
740
741    if (firstiter && firstiter != Py_None) {
742        if (!PyCallable_Check(firstiter)) {
743            PyErr_Format(PyExc_TypeError,
744                         "callable firstiter expected, got %.50s",
745                         Py_TYPE(firstiter)->tp_name);
746            return NULL;
747        }
748        _PyEval_SetAsyncGenFirstiter(firstiter);
749    }
750    else if (firstiter == Py_None) {
751        _PyEval_SetAsyncGenFirstiter(NULL);
752    }
753
754    Py_RETURN_NONE;
755}
756
757PyDoc_STRVAR(set_asyncgen_hooks_doc,
758"set_asyncgen_hooks(*, firstiter=None, finalizer=None)\n\
759\n\
760Set a finalizer for async generators objects."
761);
762
763static PyObject *
764sys_get_asyncgen_hooks(PyObject *self, PyObject *args)
765{
766    PyObject *res;
767    PyObject *firstiter = _PyEval_GetAsyncGenFirstiter();
768    PyObject *finalizer = _PyEval_GetAsyncGenFinalizer();
769
770    res = PyStructSequence_New(&AsyncGenHooksType);
771    if (res == NULL) {
772        return NULL;
773    }
774
775    if (firstiter == NULL) {
776        firstiter = Py_None;
777    }
778
779    if (finalizer == NULL) {
780        finalizer = Py_None;
781    }
782
783    Py_INCREF(firstiter);
784    PyStructSequence_SET_ITEM(res, 0, firstiter);
785
786    Py_INCREF(finalizer);
787    PyStructSequence_SET_ITEM(res, 1, finalizer);
788
789    return res;
790}
791
792PyDoc_STRVAR(get_asyncgen_hooks_doc,
793"get_asyncgen_hooks()\n\
794\n\
795Return a namedtuple of installed asynchronous generators hooks \
796(firstiter, finalizer)."
797);
798
799
800static PyTypeObject Hash_InfoType;
801
802PyDoc_STRVAR(hash_info_doc,
803"hash_info\n\
804\n\
805A struct sequence providing parameters used for computing\n\
806hashes. The attributes are read only.");
807
808static PyStructSequence_Field hash_info_fields[] = {
809    {"width", "width of the type used for hashing, in bits"},
810    {"modulus", "prime number giving the modulus on which the hash "
811                "function is based"},
812    {"inf", "value to be used for hash of a positive infinity"},
813    {"nan", "value to be used for hash of a nan"},
814    {"imag", "multiplier used for the imaginary part of a complex number"},
815    {"algorithm", "name of the algorithm for hashing of str, bytes and "
816                  "memoryviews"},
817    {"hash_bits", "internal output size of hash algorithm"},
818    {"seed_bits", "seed size of hash algorithm"},
819    {"cutoff", "small string optimization cutoff"},
820    {NULL, NULL}
821};
822
823static PyStructSequence_Desc hash_info_desc = {
824    "sys.hash_info",
825    hash_info_doc,
826    hash_info_fields,
827    9,
828};
829
830static PyObject *
831get_hash_info(void)
832{
833    PyObject *hash_info;
834    int field = 0;
835    PyHash_FuncDef *hashfunc;
836    hash_info = PyStructSequence_New(&Hash_InfoType);
837    if (hash_info == NULL)
838        return NULL;
839    hashfunc = PyHash_GetFuncDef();
840    PyStructSequence_SET_ITEM(hash_info, field++,
841                              PyLong_FromLong(8*sizeof(Py_hash_t)));
842    PyStructSequence_SET_ITEM(hash_info, field++,
843                              PyLong_FromSsize_t(_PyHASH_MODULUS));
844    PyStructSequence_SET_ITEM(hash_info, field++,
845                              PyLong_FromLong(_PyHASH_INF));
846    PyStructSequence_SET_ITEM(hash_info, field++,
847                              PyLong_FromLong(_PyHASH_NAN));
848    PyStructSequence_SET_ITEM(hash_info, field++,
849                              PyLong_FromLong(_PyHASH_IMAG));
850    PyStructSequence_SET_ITEM(hash_info, field++,
851                              PyUnicode_FromString(hashfunc->name));
852    PyStructSequence_SET_ITEM(hash_info, field++,
853                              PyLong_FromLong(hashfunc->hash_bits));
854    PyStructSequence_SET_ITEM(hash_info, field++,
855                              PyLong_FromLong(hashfunc->seed_bits));
856    PyStructSequence_SET_ITEM(hash_info, field++,
857                              PyLong_FromLong(Py_HASH_CUTOFF));
858    if (PyErr_Occurred()) {
859        Py_CLEAR(hash_info);
860        return NULL;
861    }
862    return hash_info;
863}
864
865
866PyDoc_STRVAR(setrecursionlimit_doc,
867"setrecursionlimit(n)\n\
868\n\
869Set the maximum depth of the Python interpreter stack to n.  This\n\
870limit prevents infinite recursion from causing an overflow of the C\n\
871stack and crashing Python.  The highest possible limit is platform-\n\
872dependent."
873);
874
875static PyObject *
876sys_getrecursionlimit(PyObject *self)
877{
878    return PyLong_FromLong(Py_GetRecursionLimit());
879}
880
881PyDoc_STRVAR(getrecursionlimit_doc,
882"getrecursionlimit()\n\
883\n\
884Return the current value of the recursion limit, the maximum depth\n\
885of the Python interpreter stack.  This limit prevents infinite\n\
886recursion from causing an overflow of the C stack and crashing Python."
887);
888
889#ifdef MS_WINDOWS
890PyDoc_STRVAR(getwindowsversion_doc,
891"getwindowsversion()\n\
892\n\
893Return information about the running version of Windows as a named tuple.\n\
894The members are named: major, minor, build, platform, service_pack,\n\
895service_pack_major, service_pack_minor, suite_mask, and product_type. For\n\
896backward compatibility, only the first 5 items are available by indexing.\n\
897All elements are numbers, except service_pack and platform_type which are\n\
898strings, and platform_version which is a 3-tuple. Platform is always 2.\n\
899Product_type may be 1 for a workstation, 2 for a domain controller, 3 for a\n\
900server. Platform_version is a 3-tuple containing a version number that is\n\
901intended for identifying the OS rather than feature detection."
902);
903
904static PyTypeObject WindowsVersionType = {0, 0, 0, 0, 0, 0};
905
906static PyStructSequence_Field windows_version_fields[] = {
907    {"major", "Major version number"},
908    {"minor", "Minor version number"},
909    {"build", "Build number"},
910    {"platform", "Operating system platform"},
911    {"service_pack", "Latest Service Pack installed on the system"},
912    {"service_pack_major", "Service Pack major version number"},
913    {"service_pack_minor", "Service Pack minor version number"},
914    {"suite_mask", "Bit mask identifying available product suites"},
915    {"product_type", "System product type"},
916    {"platform_version", "Diagnostic version number"},
917    {0}
918};
919
920static PyStructSequence_Desc windows_version_desc = {
921    "sys.getwindowsversion",  /* name */
922    getwindowsversion_doc,    /* doc */
923    windows_version_fields,   /* fields */
924    5                         /* For backward compatibility,
925                                 only the first 5 items are accessible
926                                 via indexing, the rest are name only */
927};
928
929/* Disable deprecation warnings about GetVersionEx as the result is
930   being passed straight through to the caller, who is responsible for
931   using it correctly. */
932#pragma warning(push)
933#pragma warning(disable:4996)
934
935static PyObject *
936sys_getwindowsversion(PyObject *self)
937{
938    PyObject *version;
939    int pos = 0;
940    OSVERSIONINFOEX ver;
941    DWORD realMajor, realMinor, realBuild;
942    HANDLE hKernel32;
943    wchar_t kernel32_path[MAX_PATH];
944    LPVOID verblock;
945    DWORD verblock_size;
946
947    ver.dwOSVersionInfoSize = sizeof(ver);
948    if (!GetVersionEx((OSVERSIONINFO*) &ver))
949        return PyErr_SetFromWindowsErr(0);
950
951    version = PyStructSequence_New(&WindowsVersionType);
952    if (version == NULL)
953        return NULL;
954
955    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMajorVersion));
956    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMinorVersion));
957    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwBuildNumber));
958    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwPlatformId));
959    PyStructSequence_SET_ITEM(version, pos++, PyUnicode_FromString(ver.szCSDVersion));
960    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMajor));
961    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMinor));
962    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wSuiteMask));
963    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wProductType));
964
965    realMajor = ver.dwMajorVersion;
966    realMinor = ver.dwMinorVersion;
967    realBuild = ver.dwBuildNumber;
968
969    // GetVersion will lie if we are running in a compatibility mode.
970    // We need to read the version info from a system file resource
971    // to accurately identify the OS version. If we fail for any reason,
972    // just return whatever GetVersion said.
973    hKernel32 = GetModuleHandleW(L"kernel32.dll");
974    if (hKernel32 && GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH) &&
975        (verblock_size = GetFileVersionInfoSizeW(kernel32_path, NULL)) &&
976        (verblock = PyMem_RawMalloc(verblock_size))) {
977        VS_FIXEDFILEINFO *ffi;
978        UINT ffi_len;
979
980        if (GetFileVersionInfoW(kernel32_path, 0, verblock_size, verblock) &&
981            VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) {
982            realMajor = HIWORD(ffi->dwProductVersionMS);
983            realMinor = LOWORD(ffi->dwProductVersionMS);
984            realBuild = HIWORD(ffi->dwProductVersionLS);
985        }
986        PyMem_RawFree(verblock);
987    }
988    PyStructSequence_SET_ITEM(version, pos++, PyTuple_Pack(3,
989        PyLong_FromLong(realMajor),
990        PyLong_FromLong(realMinor),
991        PyLong_FromLong(realBuild)
992    ));
993
994    if (PyErr_Occurred()) {
995        Py_DECREF(version);
996        return NULL;
997    }
998
999    return version;
1000}
1001
1002#pragma warning(pop)
1003
1004PyDoc_STRVAR(enablelegacywindowsfsencoding_doc,
1005"_enablelegacywindowsfsencoding()\n\
1006\n\
1007Changes the default filesystem encoding to mbcs:replace for consistency\n\
1008with earlier versions of Python. See PEP 529 for more information.\n\
1009\n\
1010This is equivalent to defining the PYTHONLEGACYWINDOWSFSENCODING \n\
1011environment variable before launching Python."
1012);
1013
1014static PyObject *
1015sys_enablelegacywindowsfsencoding(PyObject *self)
1016{
1017    Py_FileSystemDefaultEncoding = "mbcs";
1018    Py_FileSystemDefaultEncodeErrors = "replace";
1019    Py_RETURN_NONE;
1020}
1021
1022#endif /* MS_WINDOWS */
1023
1024#ifdef HAVE_DLOPEN
1025static PyObject *
1026sys_setdlopenflags(PyObject *self, PyObject *args)
1027{
1028    int new_val;
1029    PyThreadState *tstate = PyThreadState_GET();
1030    if (!PyArg_ParseTuple(args, "i:setdlopenflags", &new_val))
1031        return NULL;
1032    if (!tstate)
1033        return NULL;
1034    tstate->interp->dlopenflags = new_val;
1035    Py_INCREF(Py_None);
1036    return Py_None;
1037}
1038
1039PyDoc_STRVAR(setdlopenflags_doc,
1040"setdlopenflags(n) -> None\n\
1041\n\
1042Set the flags used by the interpreter for dlopen calls, such as when the\n\
1043interpreter loads extension modules.  Among other things, this will enable\n\
1044a lazy resolving of symbols when importing a module, if called as\n\
1045sys.setdlopenflags(0).  To share symbols across extension modules, call as\n\
1046sys.setdlopenflags(os.RTLD_GLOBAL).  Symbolic names for the flag modules\n\
1047can be found in the os module (RTLD_xxx constants, e.g. os.RTLD_LAZY).");
1048
1049static PyObject *
1050sys_getdlopenflags(PyObject *self, PyObject *args)
1051{
1052    PyThreadState *tstate = PyThreadState_GET();
1053    if (!tstate)
1054        return NULL;
1055    return PyLong_FromLong(tstate->interp->dlopenflags);
1056}
1057
1058PyDoc_STRVAR(getdlopenflags_doc,
1059"getdlopenflags() -> int\n\
1060\n\
1061Return the current value of the flags that are used for dlopen calls.\n\
1062The flag constants are defined in the os module.");
1063
1064#endif  /* HAVE_DLOPEN */
1065
1066#ifdef USE_MALLOPT
1067/* Link with -lmalloc (or -lmpc) on an SGI */
1068#include <malloc.h>
1069
1070static PyObject *
1071sys_mdebug(PyObject *self, PyObject *args)
1072{
1073    int flag;
1074    if (!PyArg_ParseTuple(args, "i:mdebug", &flag))
1075        return NULL;
1076    mallopt(M_DEBUG, flag);
1077    Py_INCREF(Py_None);
1078    return Py_None;
1079}
1080#endif /* USE_MALLOPT */
1081
1082size_t
1083_PySys_GetSizeOf(PyObject *o)
1084{
1085    PyObject *res = NULL;
1086    PyObject *method;
1087    Py_ssize_t size;
1088
1089    /* Make sure the type is initialized. float gets initialized late */
1090    if (PyType_Ready(Py_TYPE(o)) < 0)
1091        return (size_t)-1;
1092
1093    method = _PyObject_LookupSpecial(o, &PyId___sizeof__);
1094    if (method == NULL) {
1095        if (!PyErr_Occurred())
1096            PyErr_Format(PyExc_TypeError,
1097                         "Type %.100s doesn't define __sizeof__",
1098                         Py_TYPE(o)->tp_name);
1099    }
1100    else {
1101        res = PyObject_CallFunctionObjArgs(method, NULL);
1102        Py_DECREF(method);
1103    }
1104
1105    if (res == NULL)
1106        return (size_t)-1;
1107
1108    size = PyLong_AsSsize_t(res);
1109    Py_DECREF(res);
1110    if (size == -1 && PyErr_Occurred())
1111        return (size_t)-1;
1112
1113    if (size < 0) {
1114        PyErr_SetString(PyExc_ValueError, "__sizeof__() should return >= 0");
1115        return (size_t)-1;
1116    }
1117
1118    /* add gc_head size */
1119    if (PyObject_IS_GC(o))
1120        return ((size_t)size) + sizeof(PyGC_Head);
1121    return (size_t)size;
1122}
1123
1124static PyObject *
1125sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
1126{
1127    static char *kwlist[] = {"object", "default", 0};
1128    size_t size;
1129    PyObject *o, *dflt = NULL;
1130
1131    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof",
1132                                     kwlist, &o, &dflt))
1133        return NULL;
1134
1135    size = _PySys_GetSizeOf(o);
1136
1137    if (size == (size_t)-1 && PyErr_Occurred()) {
1138        /* Has a default value been given */
1139        if (dflt != NULL && PyErr_ExceptionMatches(PyExc_TypeError)) {
1140            PyErr_Clear();
1141            Py_INCREF(dflt);
1142            return dflt;
1143        }
1144        else
1145            return NULL;
1146    }
1147
1148    return PyLong_FromSize_t(size);
1149}
1150
1151PyDoc_STRVAR(getsizeof_doc,
1152"getsizeof(object, default) -> int\n\
1153\n\
1154Return the size of object in bytes.");
1155
1156static PyObject *
1157sys_getrefcount(PyObject *self, PyObject *arg)
1158{
1159    return PyLong_FromSsize_t(arg->ob_refcnt);
1160}
1161
1162#ifdef Py_REF_DEBUG
1163static PyObject *
1164sys_gettotalrefcount(PyObject *self)
1165{
1166    return PyLong_FromSsize_t(_Py_GetRefTotal());
1167}
1168#endif /* Py_REF_DEBUG */
1169
1170PyDoc_STRVAR(getrefcount_doc,
1171"getrefcount(object) -> integer\n\
1172\n\
1173Return the reference count of object.  The count returned is generally\n\
1174one higher than you might expect, because it includes the (temporary)\n\
1175reference as an argument to getrefcount()."
1176);
1177
1178static PyObject *
1179sys_getallocatedblocks(PyObject *self)
1180{
1181    return PyLong_FromSsize_t(_Py_GetAllocatedBlocks());
1182}
1183
1184PyDoc_STRVAR(getallocatedblocks_doc,
1185"getallocatedblocks() -> integer\n\
1186\n\
1187Return the number of memory blocks currently allocated, regardless of their\n\
1188size."
1189);
1190
1191#ifdef COUNT_ALLOCS
1192static PyObject *
1193sys_getcounts(PyObject *self)
1194{
1195    extern PyObject *get_counts(void);
1196
1197    return get_counts();
1198}
1199#endif
1200
1201PyDoc_STRVAR(getframe_doc,
1202"_getframe([depth]) -> frameobject\n\
1203\n\
1204Return a frame object from the call stack.  If optional integer depth is\n\
1205given, return the frame object that many calls below the top of the stack.\n\
1206If that is deeper than the call stack, ValueError is raised.  The default\n\
1207for depth is zero, returning the frame at the top of the call stack.\n\
1208\n\
1209This function should be used for internal and specialized\n\
1210purposes only."
1211);
1212
1213static PyObject *
1214sys_getframe(PyObject *self, PyObject *args)
1215{
1216    PyFrameObject *f = PyThreadState_GET()->frame;
1217    int depth = -1;
1218
1219    if (!PyArg_ParseTuple(args, "|i:_getframe", &depth))
1220        return NULL;
1221
1222    while (depth > 0 && f != NULL) {
1223        f = f->f_back;
1224        --depth;
1225    }
1226    if (f == NULL) {
1227        PyErr_SetString(PyExc_ValueError,
1228                        "call stack is not deep enough");
1229        return NULL;
1230    }
1231    Py_INCREF(f);
1232    return (PyObject*)f;
1233}
1234
1235PyDoc_STRVAR(current_frames_doc,
1236"_current_frames() -> dictionary\n\
1237\n\
1238Return a dictionary mapping each current thread T's thread id to T's\n\
1239current stack frame.\n\
1240\n\
1241This function should be used for specialized purposes only."
1242);
1243
1244static PyObject *
1245sys_current_frames(PyObject *self, PyObject *noargs)
1246{
1247    return _PyThread_CurrentFrames();
1248}
1249
1250PyDoc_STRVAR(call_tracing_doc,
1251"call_tracing(func, args) -> object\n\
1252\n\
1253Call func(*args), while tracing is enabled.  The tracing state is\n\
1254saved, and restored afterwards.  This is intended to be called from\n\
1255a debugger from a checkpoint, to recursively debug some other code."
1256);
1257
1258static PyObject *
1259sys_call_tracing(PyObject *self, PyObject *args)
1260{
1261    PyObject *func, *funcargs;
1262    if (!PyArg_ParseTuple(args, "OO!:call_tracing", &func, &PyTuple_Type, &funcargs))
1263        return NULL;
1264    return _PyEval_CallTracing(func, funcargs);
1265}
1266
1267PyDoc_STRVAR(callstats_doc,
1268"callstats() -> tuple of integers\n\
1269\n\
1270Return a tuple of function call statistics, if CALL_PROFILE was defined\n\
1271when Python was built.  Otherwise, return None.\n\
1272\n\
1273When enabled, this function returns detailed, implementation-specific\n\
1274details about the number of function calls executed. The return value is\n\
1275a 11-tuple where the entries in the tuple are counts of:\n\
12760. all function calls\n\
12771. calls to PyFunction_Type objects\n\
12782. PyFunction calls that do not create an argument tuple\n\
12793. PyFunction calls that do not create an argument tuple\n\
1280   and bypass PyEval_EvalCodeEx()\n\
12814. PyMethod calls\n\
12825. PyMethod calls on bound methods\n\
12836. PyType calls\n\
12847. PyCFunction calls\n\
12858. generator calls\n\
12869. All other calls\n\
128710. Number of stack pops performed by call_function()"
1288);
1289
1290#ifdef __cplusplus
1291extern "C" {
1292#endif
1293
1294static PyObject *
1295sys_debugmallocstats(PyObject *self, PyObject *args)
1296{
1297#ifdef WITH_PYMALLOC
1298    if (_PyMem_PymallocEnabled()) {
1299        _PyObject_DebugMallocStats(stderr);
1300        fputc('\n', stderr);
1301    }
1302#endif
1303    _PyObject_DebugTypeStats(stderr);
1304
1305    Py_RETURN_NONE;
1306}
1307PyDoc_STRVAR(debugmallocstats_doc,
1308"_debugmallocstats()\n\
1309\n\
1310Print summary info to stderr about the state of\n\
1311pymalloc's structures.\n\
1312\n\
1313In Py_DEBUG mode, also perform some expensive internal consistency\n\
1314checks.\n\
1315");
1316
1317#ifdef Py_TRACE_REFS
1318/* Defined in objects.c because it uses static globals if that file */
1319extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
1320#endif
1321
1322#ifdef DYNAMIC_EXECUTION_PROFILE
1323/* Defined in ceval.c because it uses static globals if that file */
1324extern PyObject *_Py_GetDXProfile(PyObject *,  PyObject *);
1325#endif
1326
1327#ifdef __cplusplus
1328}
1329#endif
1330
1331static PyObject *
1332sys_clear_type_cache(PyObject* self, PyObject* args)
1333{
1334    PyType_ClearCache();
1335    Py_RETURN_NONE;
1336}
1337
1338PyDoc_STRVAR(sys_clear_type_cache__doc__,
1339"_clear_type_cache() -> None\n\
1340Clear the internal type lookup cache.");
1341
1342static PyObject *
1343sys_is_finalizing(PyObject* self, PyObject* args)
1344{
1345    return PyBool_FromLong(_Py_Finalizing != NULL);
1346}
1347
1348PyDoc_STRVAR(is_finalizing_doc,
1349"is_finalizing()\n\
1350Return True if Python is exiting.");
1351
1352
1353static PyMethodDef sys_methods[] = {
1354    /* Might as well keep this in alphabetic order */
1355    {"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS,
1356     callstats_doc},
1357    {"_clear_type_cache",       sys_clear_type_cache,     METH_NOARGS,
1358     sys_clear_type_cache__doc__},
1359    {"_current_frames", sys_current_frames, METH_NOARGS,
1360     current_frames_doc},
1361    {"displayhook",     sys_displayhook, METH_O, displayhook_doc},
1362    {"exc_info",        sys_exc_info, METH_NOARGS, exc_info_doc},
1363    {"excepthook",      sys_excepthook, METH_VARARGS, excepthook_doc},
1364    {"exit",            sys_exit, METH_VARARGS, exit_doc},
1365    {"getdefaultencoding", (PyCFunction)sys_getdefaultencoding,
1366     METH_NOARGS, getdefaultencoding_doc},
1367#ifdef HAVE_DLOPEN
1368    {"getdlopenflags", (PyCFunction)sys_getdlopenflags, METH_NOARGS,
1369     getdlopenflags_doc},
1370#endif
1371    {"getallocatedblocks", (PyCFunction)sys_getallocatedblocks, METH_NOARGS,
1372      getallocatedblocks_doc},
1373#ifdef COUNT_ALLOCS
1374    {"getcounts",       (PyCFunction)sys_getcounts, METH_NOARGS},
1375#endif
1376#ifdef DYNAMIC_EXECUTION_PROFILE
1377    {"getdxp",          _Py_GetDXProfile, METH_VARARGS},
1378#endif
1379    {"getfilesystemencoding", (PyCFunction)sys_getfilesystemencoding,
1380     METH_NOARGS, getfilesystemencoding_doc},
1381    { "getfilesystemencodeerrors", (PyCFunction)sys_getfilesystemencodeerrors,
1382     METH_NOARGS, getfilesystemencodeerrors_doc },
1383#ifdef Py_TRACE_REFS
1384    {"getobjects",      _Py_GetObjects, METH_VARARGS},
1385#endif
1386#ifdef Py_REF_DEBUG
1387    {"gettotalrefcount", (PyCFunction)sys_gettotalrefcount, METH_NOARGS},
1388#endif
1389    {"getrefcount",     (PyCFunction)sys_getrefcount, METH_O, getrefcount_doc},
1390    {"getrecursionlimit", (PyCFunction)sys_getrecursionlimit, METH_NOARGS,
1391     getrecursionlimit_doc},
1392    {"getsizeof",   (PyCFunction)sys_getsizeof,
1393     METH_VARARGS | METH_KEYWORDS, getsizeof_doc},
1394    {"_getframe", sys_getframe, METH_VARARGS, getframe_doc},
1395#ifdef MS_WINDOWS
1396    {"getwindowsversion", (PyCFunction)sys_getwindowsversion, METH_NOARGS,
1397     getwindowsversion_doc},
1398    {"_enablelegacywindowsfsencoding", (PyCFunction)sys_enablelegacywindowsfsencoding,
1399     METH_NOARGS, enablelegacywindowsfsencoding_doc },
1400#endif /* MS_WINDOWS */
1401    {"intern",          sys_intern,     METH_VARARGS, intern_doc},
1402    {"is_finalizing",   sys_is_finalizing, METH_NOARGS, is_finalizing_doc},
1403#ifdef USE_MALLOPT
1404    {"mdebug",          sys_mdebug, METH_VARARGS},
1405#endif
1406    {"setcheckinterval",        sys_setcheckinterval, METH_VARARGS,
1407     setcheckinterval_doc},
1408    {"getcheckinterval",        sys_getcheckinterval, METH_NOARGS,
1409     getcheckinterval_doc},
1410#ifdef WITH_THREAD
1411    {"setswitchinterval",       sys_setswitchinterval, METH_VARARGS,
1412     setswitchinterval_doc},
1413    {"getswitchinterval",       sys_getswitchinterval, METH_NOARGS,
1414     getswitchinterval_doc},
1415#endif
1416#ifdef HAVE_DLOPEN
1417    {"setdlopenflags", sys_setdlopenflags, METH_VARARGS,
1418     setdlopenflags_doc},
1419#endif
1420    {"setprofile",      sys_setprofile, METH_O, setprofile_doc},
1421    {"getprofile",      sys_getprofile, METH_NOARGS, getprofile_doc},
1422    {"setrecursionlimit", sys_setrecursionlimit, METH_VARARGS,
1423     setrecursionlimit_doc},
1424    {"settrace",        sys_settrace, METH_O, settrace_doc},
1425    {"gettrace",        sys_gettrace, METH_NOARGS, gettrace_doc},
1426    {"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc},
1427    {"_debugmallocstats", sys_debugmallocstats, METH_NOARGS,
1428     debugmallocstats_doc},
1429    {"set_coroutine_wrapper", sys_set_coroutine_wrapper, METH_O,
1430     set_coroutine_wrapper_doc},
1431    {"get_coroutine_wrapper", sys_get_coroutine_wrapper, METH_NOARGS,
1432     get_coroutine_wrapper_doc},
1433    {"set_asyncgen_hooks", (PyCFunction)sys_set_asyncgen_hooks,
1434     METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc},
1435    {"get_asyncgen_hooks", sys_get_asyncgen_hooks, METH_NOARGS,
1436     get_asyncgen_hooks_doc},
1437    {NULL,              NULL}           /* sentinel */
1438};
1439
1440static PyObject *
1441list_builtin_module_names(void)
1442{
1443    PyObject *list = PyList_New(0);
1444    int i;
1445    if (list == NULL)
1446        return NULL;
1447    for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
1448        PyObject *name = PyUnicode_FromString(
1449            PyImport_Inittab[i].name);
1450        if (name == NULL)
1451            break;
1452        PyList_Append(list, name);
1453        Py_DECREF(name);
1454    }
1455    if (PyList_Sort(list) != 0) {
1456        Py_DECREF(list);
1457        list = NULL;
1458    }
1459    if (list) {
1460        PyObject *v = PyList_AsTuple(list);
1461        Py_DECREF(list);
1462        list = v;
1463    }
1464    return list;
1465}
1466
1467static PyObject *warnoptions = NULL;
1468
1469void
1470PySys_ResetWarnOptions(void)
1471{
1472    if (warnoptions == NULL || !PyList_Check(warnoptions))
1473        return;
1474    PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
1475}
1476
1477void
1478PySys_AddWarnOptionUnicode(PyObject *unicode)
1479{
1480    if (warnoptions == NULL || !PyList_Check(warnoptions)) {
1481        Py_XDECREF(warnoptions);
1482        warnoptions = PyList_New(0);
1483        if (warnoptions == NULL)
1484            return;
1485    }
1486    PyList_Append(warnoptions, unicode);
1487}
1488
1489void
1490PySys_AddWarnOption(const wchar_t *s)
1491{
1492    PyObject *unicode;
1493    unicode = PyUnicode_FromWideChar(s, -1);
1494    if (unicode == NULL)
1495        return;
1496    PySys_AddWarnOptionUnicode(unicode);
1497    Py_DECREF(unicode);
1498}
1499
1500int
1501PySys_HasWarnOptions(void)
1502{
1503    return (warnoptions != NULL && (PyList_Size(warnoptions) > 0)) ? 1 : 0;
1504}
1505
1506static PyObject *xoptions = NULL;
1507
1508static PyObject *
1509get_xoptions(void)
1510{
1511    if (xoptions == NULL || !PyDict_Check(xoptions)) {
1512        Py_XDECREF(xoptions);
1513        xoptions = PyDict_New();
1514    }
1515    return xoptions;
1516}
1517
1518void
1519PySys_AddXOption(const wchar_t *s)
1520{
1521    PyObject *opts;
1522    PyObject *name = NULL, *value = NULL;
1523    const wchar_t *name_end;
1524
1525    opts = get_xoptions();
1526    if (opts == NULL)
1527        goto error;
1528
1529    name_end = wcschr(s, L'=');
1530    if (!name_end) {
1531        name = PyUnicode_FromWideChar(s, -1);
1532        value = Py_True;
1533        Py_INCREF(value);
1534    }
1535    else {
1536        name = PyUnicode_FromWideChar(s, name_end - s);
1537        value = PyUnicode_FromWideChar(name_end + 1, -1);
1538    }
1539    if (name == NULL || value == NULL)
1540        goto error;
1541    PyDict_SetItem(opts, name, value);
1542    Py_DECREF(name);
1543    Py_DECREF(value);
1544    return;
1545
1546error:
1547    Py_XDECREF(name);
1548    Py_XDECREF(value);
1549    /* No return value, therefore clear error state if possible */
1550    if (_PyThreadState_UncheckedGet())
1551        PyErr_Clear();
1552}
1553
1554PyObject *
1555PySys_GetXOptions(void)
1556{
1557    return get_xoptions();
1558}
1559
1560/* XXX This doc string is too long to be a single string literal in VC++ 5.0.
1561   Two literals concatenated works just fine.  If you have a K&R compiler
1562   or other abomination that however *does* understand longer strings,
1563   get rid of the !!! comment in the middle and the quotes that surround it. */
1564PyDoc_VAR(sys_doc) =
1565PyDoc_STR(
1566"This module provides access to some objects used or maintained by the\n\
1567interpreter and to functions that interact strongly with the interpreter.\n\
1568\n\
1569Dynamic objects:\n\
1570\n\
1571argv -- command line arguments; argv[0] is the script pathname if known\n\
1572path -- module search path; path[0] is the script directory, else ''\n\
1573modules -- dictionary of loaded modules\n\
1574\n\
1575displayhook -- called to show results in an interactive session\n\
1576excepthook -- called to handle any uncaught exception other than SystemExit\n\
1577  To customize printing in an interactive session or to install a custom\n\
1578  top-level exception handler, assign other functions to replace these.\n\
1579\n\
1580stdin -- standard input file object; used by input()\n\
1581stdout -- standard output file object; used by print()\n\
1582stderr -- standard error object; used for error messages\n\
1583  By assigning other file objects (or objects that behave like files)\n\
1584  to these, it is possible to redirect all of the interpreter's I/O.\n\
1585\n\
1586last_type -- type of last uncaught exception\n\
1587last_value -- value of last uncaught exception\n\
1588last_traceback -- traceback of last uncaught exception\n\
1589  These three are only available in an interactive session after a\n\
1590  traceback has been printed.\n\
1591"
1592)
1593/* concatenating string here */
1594PyDoc_STR(
1595"\n\
1596Static objects:\n\
1597\n\
1598builtin_module_names -- tuple of module names built into this interpreter\n\
1599copyright -- copyright notice pertaining to this interpreter\n\
1600exec_prefix -- prefix used to find the machine-specific Python library\n\
1601executable -- absolute path of the executable binary of the Python interpreter\n\
1602float_info -- a struct sequence with information about the float implementation.\n\
1603float_repr_style -- string indicating the style of repr() output for floats\n\
1604hash_info -- a struct sequence with information about the hash algorithm.\n\
1605hexversion -- version information encoded as a single integer\n\
1606implementation -- Python implementation information.\n\
1607int_info -- a struct sequence with information about the int implementation.\n\
1608maxsize -- the largest supported length of containers.\n\
1609maxunicode -- the value of the largest Unicode code point\n\
1610platform -- platform identifier\n\
1611prefix -- prefix used to find the Python library\n\
1612thread_info -- a struct sequence with information about the thread implementation.\n\
1613version -- the version of this interpreter as a string\n\
1614version_info -- version information as a named tuple\n\
1615"
1616)
1617#ifdef MS_COREDLL
1618/* concatenating string here */
1619PyDoc_STR(
1620"dllhandle -- [Windows only] integer handle of the Python DLL\n\
1621winver -- [Windows only] version number of the Python DLL\n\
1622"
1623)
1624#endif /* MS_COREDLL */
1625#ifdef MS_WINDOWS
1626/* concatenating string here */
1627PyDoc_STR(
1628"_enablelegacywindowsfsencoding -- [Windows only] \n\
1629"
1630)
1631#endif
1632PyDoc_STR(
1633"__stdin__ -- the original stdin; don't touch!\n\
1634__stdout__ -- the original stdout; don't touch!\n\
1635__stderr__ -- the original stderr; don't touch!\n\
1636__displayhook__ -- the original displayhook; don't touch!\n\
1637__excepthook__ -- the original excepthook; don't touch!\n\
1638\n\
1639Functions:\n\
1640\n\
1641displayhook() -- print an object to the screen, and save it in builtins._\n\
1642excepthook() -- print an exception and its traceback to sys.stderr\n\
1643exc_info() -- return thread-safe information about the current exception\n\
1644exit() -- exit the interpreter by raising SystemExit\n\
1645getdlopenflags() -- returns flags to be used for dlopen() calls\n\
1646getprofile() -- get the global profiling function\n\
1647getrefcount() -- return the reference count for an object (plus one :-)\n\
1648getrecursionlimit() -- return the max recursion depth for the interpreter\n\
1649getsizeof() -- return the size of an object in bytes\n\
1650gettrace() -- get the global debug tracing function\n\
1651setcheckinterval() -- control how often the interpreter checks for events\n\
1652setdlopenflags() -- set the flags to be used for dlopen() calls\n\
1653setprofile() -- set the global profiling function\n\
1654setrecursionlimit() -- set the max recursion depth for the interpreter\n\
1655settrace() -- set the global debug tracing function\n\
1656"
1657)
1658/* end of sys_doc */ ;
1659
1660
1661PyDoc_STRVAR(flags__doc__,
1662"sys.flags\n\
1663\n\
1664Flags provided through command line arguments or environment vars.");
1665
1666static PyTypeObject FlagsType;
1667
1668static PyStructSequence_Field flags_fields[] = {
1669    {"debug",                   "-d"},
1670    {"inspect",                 "-i"},
1671    {"interactive",             "-i"},
1672    {"optimize",                "-O or -OO"},
1673    {"dont_write_bytecode",     "-B"},
1674    {"no_user_site",            "-s"},
1675    {"no_site",                 "-S"},
1676    {"ignore_environment",      "-E"},
1677    {"verbose",                 "-v"},
1678    /* {"unbuffered",                   "-u"}, */
1679    /* {"skip_first",                   "-x"}, */
1680    {"bytes_warning",           "-b"},
1681    {"quiet",                   "-q"},
1682    {"hash_randomization",      "-R"},
1683    {"isolated",                "-I"},
1684    {0}
1685};
1686
1687static PyStructSequence_Desc flags_desc = {
1688    "sys.flags",        /* name */
1689    flags__doc__,       /* doc */
1690    flags_fields,       /* fields */
1691    13
1692};
1693
1694static PyObject*
1695make_flags(void)
1696{
1697    int pos = 0;
1698    PyObject *seq;
1699
1700    seq = PyStructSequence_New(&FlagsType);
1701    if (seq == NULL)
1702        return NULL;
1703
1704#define SetFlag(flag) \
1705    PyStructSequence_SET_ITEM(seq, pos++, PyLong_FromLong(flag))
1706
1707    SetFlag(Py_DebugFlag);
1708    SetFlag(Py_InspectFlag);
1709    SetFlag(Py_InteractiveFlag);
1710    SetFlag(Py_OptimizeFlag);
1711    SetFlag(Py_DontWriteBytecodeFlag);
1712    SetFlag(Py_NoUserSiteDirectory);
1713    SetFlag(Py_NoSiteFlag);
1714    SetFlag(Py_IgnoreEnvironmentFlag);
1715    SetFlag(Py_VerboseFlag);
1716    /* SetFlag(saw_unbuffered_flag); */
1717    /* SetFlag(skipfirstline); */
1718    SetFlag(Py_BytesWarningFlag);
1719    SetFlag(Py_QuietFlag);
1720    SetFlag(Py_HashRandomizationFlag);
1721    SetFlag(Py_IsolatedFlag);
1722#undef SetFlag
1723
1724    if (PyErr_Occurred()) {
1725        Py_DECREF(seq);
1726        return NULL;
1727    }
1728    return seq;
1729}
1730
1731PyDoc_STRVAR(version_info__doc__,
1732"sys.version_info\n\
1733\n\
1734Version information as a named tuple.");
1735
1736static PyTypeObject VersionInfoType;
1737
1738static PyStructSequence_Field version_info_fields[] = {
1739    {"major", "Major release number"},
1740    {"minor", "Minor release number"},
1741    {"micro", "Patch release number"},
1742    {"releaselevel", "'alpha', 'beta', 'candidate', or 'final'"},
1743    {"serial", "Serial release number"},
1744    {0}
1745};
1746
1747static PyStructSequence_Desc version_info_desc = {
1748    "sys.version_info",     /* name */
1749    version_info__doc__,    /* doc */
1750    version_info_fields,    /* fields */
1751    5
1752};
1753
1754static PyObject *
1755make_version_info(void)
1756{
1757    PyObject *version_info;
1758    char *s;
1759    int pos = 0;
1760
1761    version_info = PyStructSequence_New(&VersionInfoType);
1762    if (version_info == NULL) {
1763        return NULL;
1764    }
1765
1766    /*
1767     * These release level checks are mutually exclusive and cover
1768     * the field, so don't get too fancy with the pre-processor!
1769     */
1770#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
1771    s = "alpha";
1772#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
1773    s = "beta";
1774#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
1775    s = "candidate";
1776#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
1777    s = "final";
1778#endif
1779
1780#define SetIntItem(flag) \
1781    PyStructSequence_SET_ITEM(version_info, pos++, PyLong_FromLong(flag))
1782#define SetStrItem(flag) \
1783    PyStructSequence_SET_ITEM(version_info, pos++, PyUnicode_FromString(flag))
1784
1785    SetIntItem(PY_MAJOR_VERSION);
1786    SetIntItem(PY_MINOR_VERSION);
1787    SetIntItem(PY_MICRO_VERSION);
1788    SetStrItem(s);
1789    SetIntItem(PY_RELEASE_SERIAL);
1790#undef SetIntItem
1791#undef SetStrItem
1792
1793    if (PyErr_Occurred()) {
1794        Py_CLEAR(version_info);
1795        return NULL;
1796    }
1797    return version_info;
1798}
1799
1800/* sys.implementation values */
1801#define NAME "cpython"
1802const char *_PySys_ImplName = NAME;
1803#define MAJOR Py_STRINGIFY(PY_MAJOR_VERSION)
1804#define MINOR Py_STRINGIFY(PY_MINOR_VERSION)
1805#define TAG NAME "-" MAJOR MINOR
1806const char *_PySys_ImplCacheTag = TAG;
1807#undef NAME
1808#undef MAJOR
1809#undef MINOR
1810#undef TAG
1811
1812static PyObject *
1813make_impl_info(PyObject *version_info)
1814{
1815    int res;
1816    PyObject *impl_info, *value, *ns;
1817
1818    impl_info = PyDict_New();
1819    if (impl_info == NULL)
1820        return NULL;
1821
1822    /* populate the dict */
1823
1824    value = PyUnicode_FromString(_PySys_ImplName);
1825    if (value == NULL)
1826        goto error;
1827    res = PyDict_SetItemString(impl_info, "name", value);
1828    Py_DECREF(value);
1829    if (res < 0)
1830        goto error;
1831
1832    value = PyUnicode_FromString(_PySys_ImplCacheTag);
1833    if (value == NULL)
1834        goto error;
1835    res = PyDict_SetItemString(impl_info, "cache_tag", value);
1836    Py_DECREF(value);
1837    if (res < 0)
1838        goto error;
1839
1840    res = PyDict_SetItemString(impl_info, "version", version_info);
1841    if (res < 0)
1842        goto error;
1843
1844    value = PyLong_FromLong(PY_VERSION_HEX);
1845    if (value == NULL)
1846        goto error;
1847    res = PyDict_SetItemString(impl_info, "hexversion", value);
1848    Py_DECREF(value);
1849    if (res < 0)
1850        goto error;
1851
1852#ifdef MULTIARCH
1853    value = PyUnicode_FromString(MULTIARCH);
1854    if (value == NULL)
1855        goto error;
1856    res = PyDict_SetItemString(impl_info, "_multiarch", value);
1857    Py_DECREF(value);
1858    if (res < 0)
1859        goto error;
1860#endif
1861
1862    /* dict ready */
1863
1864    ns = _PyNamespace_New(impl_info);
1865    Py_DECREF(impl_info);
1866    return ns;
1867
1868error:
1869    Py_CLEAR(impl_info);
1870    return NULL;
1871}
1872
1873static struct PyModuleDef sysmodule = {
1874    PyModuleDef_HEAD_INIT,
1875    "sys",
1876    sys_doc,
1877    -1, /* multiple "initialization" just copies the module dict. */
1878    sys_methods,
1879    NULL,
1880    NULL,
1881    NULL,
1882    NULL
1883};
1884
1885PyObject *
1886_PySys_Init(void)
1887{
1888    PyObject *m, *sysdict, *version_info;
1889    int res;
1890
1891    m = PyModule_Create(&sysmodule);
1892    if (m == NULL)
1893        return NULL;
1894    sysdict = PyModule_GetDict(m);
1895#define SET_SYS_FROM_STRING_BORROW(key, value)             \
1896    do {                                                   \
1897        PyObject *v = (value);                             \
1898        if (v == NULL)                                     \
1899            return NULL;                                   \
1900        res = PyDict_SetItemString(sysdict, key, v);       \
1901        if (res < 0) {                                     \
1902            return NULL;                                   \
1903        }                                                  \
1904    } while (0)
1905#define SET_SYS_FROM_STRING(key, value)                    \
1906    do {                                                   \
1907        PyObject *v = (value);                             \
1908        if (v == NULL)                                     \
1909            return NULL;                                   \
1910        res = PyDict_SetItemString(sysdict, key, v);       \
1911        Py_DECREF(v);                                      \
1912        if (res < 0) {                                     \
1913            return NULL;                                   \
1914        }                                                  \
1915    } while (0)
1916
1917    /* Check that stdin is not a directory
1918    Using shell redirection, you can redirect stdin to a directory,
1919    crashing the Python interpreter. Catch this common mistake here
1920    and output a useful error message. Note that under MS Windows,
1921    the shell already prevents that. */
1922#if !defined(MS_WINDOWS)
1923    {
1924        struct _Py_stat_struct sb;
1925        if (_Py_fstat_noraise(fileno(stdin), &sb) == 0 &&
1926            S_ISDIR(sb.st_mode)) {
1927            /* There's nothing more we can do. */
1928            /* Py_FatalError() will core dump, so just exit. */
1929            PySys_WriteStderr("Python error: <stdin> is a directory, cannot continue\n");
1930            exit(EXIT_FAILURE);
1931        }
1932    }
1933#endif
1934
1935    /* stdin/stdout/stderr are set in pylifecycle.c */
1936
1937    SET_SYS_FROM_STRING_BORROW("__displayhook__",
1938                               PyDict_GetItemString(sysdict, "displayhook"));
1939    SET_SYS_FROM_STRING_BORROW("__excepthook__",
1940                               PyDict_GetItemString(sysdict, "excepthook"));
1941    SET_SYS_FROM_STRING("version",
1942                         PyUnicode_FromString(Py_GetVersion()));
1943    SET_SYS_FROM_STRING("hexversion",
1944                         PyLong_FromLong(PY_VERSION_HEX));
1945    SET_SYS_FROM_STRING("_git",
1946                        Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(),
1947                                      _Py_gitversion()));
1948    SET_SYS_FROM_STRING("dont_write_bytecode",
1949                         PyBool_FromLong(Py_DontWriteBytecodeFlag));
1950    SET_SYS_FROM_STRING("api_version",
1951                        PyLong_FromLong(PYTHON_API_VERSION));
1952    SET_SYS_FROM_STRING("copyright",
1953                        PyUnicode_FromString(Py_GetCopyright()));
1954    SET_SYS_FROM_STRING("platform",
1955                        PyUnicode_FromString(Py_GetPlatform()));
1956    SET_SYS_FROM_STRING("executable",
1957                        PyUnicode_FromWideChar(
1958                               Py_GetProgramFullPath(), -1));
1959    SET_SYS_FROM_STRING("prefix",
1960                        PyUnicode_FromWideChar(Py_GetPrefix(), -1));
1961    SET_SYS_FROM_STRING("exec_prefix",
1962                        PyUnicode_FromWideChar(Py_GetExecPrefix(), -1));
1963    SET_SYS_FROM_STRING("base_prefix",
1964                        PyUnicode_FromWideChar(Py_GetPrefix(), -1));
1965    SET_SYS_FROM_STRING("base_exec_prefix",
1966                        PyUnicode_FromWideChar(Py_GetExecPrefix(), -1));
1967    SET_SYS_FROM_STRING("maxsize",
1968                        PyLong_FromSsize_t(PY_SSIZE_T_MAX));
1969    SET_SYS_FROM_STRING("float_info",
1970                        PyFloat_GetInfo());
1971    SET_SYS_FROM_STRING("int_info",
1972                        PyLong_GetInfo());
1973    /* initialize hash_info */
1974    if (Hash_InfoType.tp_name == NULL) {
1975        if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0)
1976            return NULL;
1977    }
1978    SET_SYS_FROM_STRING("hash_info",
1979                        get_hash_info());
1980    SET_SYS_FROM_STRING("maxunicode",
1981                        PyLong_FromLong(0x10FFFF));
1982    SET_SYS_FROM_STRING("builtin_module_names",
1983                        list_builtin_module_names());
1984#if PY_BIG_ENDIAN
1985    SET_SYS_FROM_STRING("byteorder",
1986                        PyUnicode_FromString("big"));
1987#else
1988    SET_SYS_FROM_STRING("byteorder",
1989                        PyUnicode_FromString("little"));
1990#endif
1991
1992#ifdef MS_COREDLL
1993    SET_SYS_FROM_STRING("dllhandle",
1994                        PyLong_FromVoidPtr(PyWin_DLLhModule));
1995    SET_SYS_FROM_STRING("winver",
1996                        PyUnicode_FromString(PyWin_DLLVersionString));
1997#endif
1998#ifdef ABIFLAGS
1999    SET_SYS_FROM_STRING("abiflags",
2000                        PyUnicode_FromString(ABIFLAGS));
2001#endif
2002    if (warnoptions == NULL) {
2003        warnoptions = PyList_New(0);
2004        if (warnoptions == NULL)
2005            return NULL;
2006    }
2007    else {
2008        Py_INCREF(warnoptions);
2009    }
2010    SET_SYS_FROM_STRING_BORROW("warnoptions", warnoptions);
2011
2012    SET_SYS_FROM_STRING_BORROW("_xoptions", get_xoptions());
2013
2014    /* version_info */
2015    if (VersionInfoType.tp_name == NULL) {
2016        if (PyStructSequence_InitType2(&VersionInfoType,
2017                                       &version_info_desc) < 0)
2018            return NULL;
2019    }
2020    version_info = make_version_info();
2021    SET_SYS_FROM_STRING("version_info", version_info);
2022    /* prevent user from creating new instances */
2023    VersionInfoType.tp_init = NULL;
2024    VersionInfoType.tp_new = NULL;
2025    res = PyDict_DelItemString(VersionInfoType.tp_dict, "__new__");
2026    if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
2027        PyErr_Clear();
2028
2029    /* implementation */
2030    SET_SYS_FROM_STRING("implementation", make_impl_info(version_info));
2031
2032    /* flags */
2033    if (FlagsType.tp_name == 0) {
2034        if (PyStructSequence_InitType2(&FlagsType, &flags_desc) < 0)
2035            return NULL;
2036    }
2037    SET_SYS_FROM_STRING("flags", make_flags());
2038    /* prevent user from creating new instances */
2039    FlagsType.tp_init = NULL;
2040    FlagsType.tp_new = NULL;
2041    res = PyDict_DelItemString(FlagsType.tp_dict, "__new__");
2042    if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
2043        PyErr_Clear();
2044
2045#if defined(MS_WINDOWS)
2046    /* getwindowsversion */
2047    if (WindowsVersionType.tp_name == 0)
2048        if (PyStructSequence_InitType2(&WindowsVersionType,
2049                                       &windows_version_desc) < 0)
2050            return NULL;
2051    /* prevent user from creating new instances */
2052    WindowsVersionType.tp_init = NULL;
2053    WindowsVersionType.tp_new = NULL;
2054    res = PyDict_DelItemString(WindowsVersionType.tp_dict, "__new__");
2055    if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
2056        PyErr_Clear();
2057#endif
2058
2059    /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */
2060#ifndef PY_NO_SHORT_FLOAT_REPR
2061    SET_SYS_FROM_STRING("float_repr_style",
2062                        PyUnicode_FromString("short"));
2063#else
2064    SET_SYS_FROM_STRING("float_repr_style",
2065                        PyUnicode_FromString("legacy"));
2066#endif
2067
2068#ifdef WITH_THREAD
2069    SET_SYS_FROM_STRING("thread_info", PyThread_GetInfo());
2070#endif
2071
2072    /* initialize asyncgen_hooks */
2073    if (AsyncGenHooksType.tp_name == NULL) {
2074        if (PyStructSequence_InitType2(
2075                &AsyncGenHooksType, &asyncgen_hooks_desc) < 0) {
2076            return NULL;
2077        }
2078    }
2079
2080#undef SET_SYS_FROM_STRING
2081#undef SET_SYS_FROM_STRING_BORROW
2082    if (PyErr_Occurred())
2083        return NULL;
2084    return m;
2085}
2086
2087static PyObject *
2088makepathobject(const wchar_t *path, wchar_t delim)
2089{
2090    int i, n;
2091    const wchar_t *p;
2092    PyObject *v, *w;
2093
2094    n = 1;
2095    p = path;
2096    while ((p = wcschr(p, delim)) != NULL) {
2097        n++;
2098        p++;
2099    }
2100    v = PyList_New(n);
2101    if (v == NULL)
2102        return NULL;
2103    for (i = 0; ; i++) {
2104        p = wcschr(path, delim);
2105        if (p == NULL)
2106            p = path + wcslen(path); /* End of string */
2107        w = PyUnicode_FromWideChar(path, (Py_ssize_t)(p - path));
2108        if (w == NULL) {
2109            Py_DECREF(v);
2110            return NULL;
2111        }
2112        PyList_SetItem(v, i, w);
2113        if (*p == '\0')
2114            break;
2115        path = p+1;
2116    }
2117    return v;
2118}
2119
2120void
2121PySys_SetPath(const wchar_t *path)
2122{
2123    PyObject *v;
2124    if ((v = makepathobject(path, DELIM)) == NULL)
2125        Py_FatalError("can't create sys.path");
2126    if (_PySys_SetObjectId(&PyId_path, v) != 0)
2127        Py_FatalError("can't assign sys.path");
2128    Py_DECREF(v);
2129}
2130
2131static PyObject *
2132makeargvobject(int argc, wchar_t **argv)
2133{
2134    PyObject *av;
2135    if (argc <= 0 || argv == NULL) {
2136        /* Ensure at least one (empty) argument is seen */
2137        static wchar_t *empty_argv[1] = {L""};
2138        argv = empty_argv;
2139        argc = 1;
2140    }
2141    av = PyList_New(argc);
2142    if (av != NULL) {
2143        int i;
2144        for (i = 0; i < argc; i++) {
2145            PyObject *v = PyUnicode_FromWideChar(argv[i], -1);
2146            if (v == NULL) {
2147                Py_DECREF(av);
2148                av = NULL;
2149                break;
2150            }
2151            PyList_SetItem(av, i, v);
2152        }
2153    }
2154    return av;
2155}
2156
2157#define _HAVE_SCRIPT_ARGUMENT(argc, argv) \
2158  (argc > 0 && argv0 != NULL && \
2159   wcscmp(argv0, L"-c") != 0 && wcscmp(argv0, L"-m") != 0)
2160
2161static void
2162sys_update_path(int argc, wchar_t **argv)
2163{
2164    wchar_t *argv0;
2165    wchar_t *p = NULL;
2166    Py_ssize_t n = 0;
2167    PyObject *a;
2168    PyObject *path;
2169#ifdef HAVE_READLINK
2170    wchar_t link[MAXPATHLEN+1];
2171    wchar_t argv0copy[2*MAXPATHLEN+1];
2172    int nr = 0;
2173#endif
2174#if defined(HAVE_REALPATH)
2175    wchar_t fullpath[MAXPATHLEN];
2176#elif defined(MS_WINDOWS)
2177    wchar_t fullpath[MAX_PATH];
2178#endif
2179
2180    path = _PySys_GetObjectId(&PyId_path);
2181    if (path == NULL)
2182        return;
2183
2184    argv0 = argv[0];
2185
2186#ifdef HAVE_READLINK
2187    if (_HAVE_SCRIPT_ARGUMENT(argc, argv))
2188        nr = _Py_wreadlink(argv0, link, MAXPATHLEN);
2189    if (nr > 0) {
2190        /* It's a symlink */
2191        link[nr] = '\0';
2192        if (link[0] == SEP)
2193            argv0 = link; /* Link to absolute path */
2194        else if (wcschr(link, SEP) == NULL)
2195            ; /* Link without path */
2196        else {
2197            /* Must join(dirname(argv0), link) */
2198            wchar_t *q = wcsrchr(argv0, SEP);
2199            if (q == NULL)
2200                argv0 = link; /* argv0 without path */
2201            else {
2202                /* Must make a copy, argv0copy has room for 2 * MAXPATHLEN */
2203                wcsncpy(argv0copy, argv0, MAXPATHLEN);
2204                q = wcsrchr(argv0copy, SEP);
2205                wcsncpy(q+1, link, MAXPATHLEN);
2206                q[MAXPATHLEN + 1] = L'\0';
2207                argv0 = argv0copy;
2208            }
2209        }
2210    }
2211#endif /* HAVE_READLINK */
2212#if SEP == '\\' /* Special case for MS filename syntax */
2213    if (_HAVE_SCRIPT_ARGUMENT(argc, argv)) {
2214        wchar_t *q;
2215#if defined(MS_WINDOWS)
2216        /* Replace the first element in argv with the full path. */
2217        wchar_t *ptemp;
2218        if (GetFullPathNameW(argv0,
2219                           Py_ARRAY_LENGTH(fullpath),
2220                           fullpath,
2221                           &ptemp)) {
2222            argv0 = fullpath;
2223        }
2224#endif
2225        p = wcsrchr(argv0, SEP);
2226        /* Test for alternate separator */
2227        q = wcsrchr(p ? p : argv0, '/');
2228        if (q != NULL)
2229            p = q;
2230        if (p != NULL) {
2231            n = p + 1 - argv0;
2232            if (n > 1 && p[-1] != ':')
2233                n--; /* Drop trailing separator */
2234        }
2235    }
2236#else /* All other filename syntaxes */
2237    if (_HAVE_SCRIPT_ARGUMENT(argc, argv)) {
2238#if defined(HAVE_REALPATH)
2239        if (_Py_wrealpath(argv0, fullpath, Py_ARRAY_LENGTH(fullpath))) {
2240            argv0 = fullpath;
2241        }
2242#endif
2243        p = wcsrchr(argv0, SEP);
2244    }
2245    if (p != NULL) {
2246        n = p + 1 - argv0;
2247#if SEP == '/' /* Special case for Unix filename syntax */
2248        if (n > 1)
2249            n--; /* Drop trailing separator */
2250#endif /* Unix */
2251    }
2252#endif /* All others */
2253    a = PyUnicode_FromWideChar(argv0, n);
2254    if (a == NULL)
2255        Py_FatalError("no mem for sys.path insertion");
2256    if (PyList_Insert(path, 0, a) < 0)
2257        Py_FatalError("sys.path.insert(0) failed");
2258    Py_DECREF(a);
2259}
2260
2261void
2262PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
2263{
2264    PyObject *av = makeargvobject(argc, argv);
2265    if (av == NULL)
2266        Py_FatalError("no mem for sys.argv");
2267    if (PySys_SetObject("argv", av) != 0)
2268        Py_FatalError("can't assign sys.argv");
2269    Py_DECREF(av);
2270    if (updatepath)
2271        sys_update_path(argc, argv);
2272}
2273
2274void
2275PySys_SetArgv(int argc, wchar_t **argv)
2276{
2277    PySys_SetArgvEx(argc, argv, Py_IsolatedFlag == 0);
2278}
2279
2280/* Reimplementation of PyFile_WriteString() no calling indirectly
2281   PyErr_CheckSignals(): avoid the call to PyObject_Str(). */
2282
2283static int
2284sys_pyfile_write_unicode(PyObject *unicode, PyObject *file)
2285{
2286    PyObject *writer = NULL, *result = NULL;
2287    int err;
2288
2289    if (file == NULL)
2290        return -1;
2291
2292    writer = _PyObject_GetAttrId(file, &PyId_write);
2293    if (writer == NULL)
2294        goto error;
2295
2296    result = _PyObject_CallArg1(writer, unicode);
2297    if (result == NULL) {
2298        goto error;
2299    } else {
2300        err = 0;
2301        goto finally;
2302    }
2303
2304error:
2305    err = -1;
2306finally:
2307    Py_XDECREF(writer);
2308    Py_XDECREF(result);
2309    return err;
2310}
2311
2312static int
2313sys_pyfile_write(const char *text, PyObject *file)
2314{
2315    PyObject *unicode = NULL;
2316    int err;
2317
2318    if (file == NULL)
2319        return -1;
2320
2321    unicode = PyUnicode_FromString(text);
2322    if (unicode == NULL)
2323        return -1;
2324
2325    err = sys_pyfile_write_unicode(unicode, file);
2326    Py_DECREF(unicode);
2327    return err;
2328}
2329
2330/* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
2331   Adapted from code submitted by Just van Rossum.
2332
2333   PySys_WriteStdout(format, ...)
2334   PySys_WriteStderr(format, ...)
2335
2336      The first function writes to sys.stdout; the second to sys.stderr.  When
2337      there is a problem, they write to the real (C level) stdout or stderr;
2338      no exceptions are raised.
2339
2340      PyErr_CheckSignals() is not called to avoid the execution of the Python
2341      signal handlers: they may raise a new exception whereas sys_write()
2342      ignores all exceptions.
2343
2344      Both take a printf-style format string as their first argument followed
2345      by a variable length argument list determined by the format string.
2346
2347      *** WARNING ***
2348
2349      The format should limit the total size of the formatted output string to
2350      1000 bytes.  In particular, this means that no unrestricted "%s" formats
2351      should occur; these should be limited using "%.<N>s where <N> is a
2352      decimal number calculated so that <N> plus the maximum size of other
2353      formatted text does not exceed 1000 bytes.  Also watch out for "%f",
2354      which can print hundreds of digits for very large numbers.
2355
2356 */
2357
2358static void
2359sys_write(_Py_Identifier *key, FILE *fp, const char *format, va_list va)
2360{
2361    PyObject *file;
2362    PyObject *error_type, *error_value, *error_traceback;
2363    char buffer[1001];
2364    int written;
2365
2366    PyErr_Fetch(&error_type, &error_value, &error_traceback);
2367    file = _PySys_GetObjectId(key);
2368    written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
2369    if (sys_pyfile_write(buffer, file) != 0) {
2370        PyErr_Clear();
2371        fputs(buffer, fp);
2372    }
2373    if (written < 0 || (size_t)written >= sizeof(buffer)) {
2374        const char *truncated = "... truncated";
2375        if (sys_pyfile_write(truncated, file) != 0)
2376            fputs(truncated, fp);
2377    }
2378    PyErr_Restore(error_type, error_value, error_traceback);
2379}
2380
2381void
2382PySys_WriteStdout(const char *format, ...)
2383{
2384    va_list va;
2385
2386    va_start(va, format);
2387    sys_write(&PyId_stdout, stdout, format, va);
2388    va_end(va);
2389}
2390
2391void
2392PySys_WriteStderr(const char *format, ...)
2393{
2394    va_list va;
2395
2396    va_start(va, format);
2397    sys_write(&PyId_stderr, stderr, format, va);
2398    va_end(va);
2399}
2400
2401static void
2402sys_format(_Py_Identifier *key, FILE *fp, const char *format, va_list va)
2403{
2404    PyObject *file, *message;
2405    PyObject *error_type, *error_value, *error_traceback;
2406    char *utf8;
2407
2408    PyErr_Fetch(&error_type, &error_value, &error_traceback);
2409    file = _PySys_GetObjectId(key);
2410    message = PyUnicode_FromFormatV(format, va);
2411    if (message != NULL) {
2412        if (sys_pyfile_write_unicode(message, file) != 0) {
2413            PyErr_Clear();
2414            utf8 = PyUnicode_AsUTF8(message);
2415            if (utf8 != NULL)
2416                fputs(utf8, fp);
2417        }
2418        Py_DECREF(message);
2419    }
2420    PyErr_Restore(error_type, error_value, error_traceback);
2421}
2422
2423void
2424PySys_FormatStdout(const char *format, ...)
2425{
2426    va_list va;
2427
2428    va_start(va, format);
2429    sys_format(&PyId_stdout, stdout, format, va);
2430    va_end(va);
2431}
2432
2433void
2434PySys_FormatStderr(const char *format, ...)
2435{
2436    va_list va;
2437
2438    va_start(va, format);
2439    sys_format(&PyId_stderr, stderr, format, va);
2440    va_end(va);
2441}
2442