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