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