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