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 int
set_async_gen_firstiter(PyObject * firstiter)1182 set_async_gen_firstiter(PyObject *firstiter)
1183 {
1184     PyThreadState *tstate = _PyThreadState_GET();
1185 
1186     if (PySys_Audit("sys.set_asyncgen_hook_firstiter", NULL) < 0) {
1187         return -1;
1188     }
1189 
1190     Py_XINCREF(firstiter);
1191     Py_XSETREF(tstate->async_gen_firstiter, firstiter);
1192     return 0;
1193 }
1194 
1195 void
_PyEval_SetAsyncGenFirstiter(PyObject * firstiter)1196 _PyEval_SetAsyncGenFirstiter(PyObject *firstiter)
1197 {
1198     if (set_async_gen_firstiter(firstiter) < 0) {
1199         PyErr_WriteUnraisable(NULL);
1200     }
1201 }
1202 
1203 static int
set_async_gen_finalizer(PyObject * finalizer)1204 set_async_gen_finalizer(PyObject *finalizer)
1205 {
1206     PyThreadState *tstate = _PyThreadState_GET();
1207 
1208     if (PySys_Audit("sys.set_asyncgen_hook_finalizer", NULL) < 0) {
1209         return -1;
1210     }
1211 
1212     Py_XINCREF(finalizer);
1213     Py_XSETREF(tstate->async_gen_finalizer, finalizer);
1214     return 0;
1215 }
1216 
1217 void
_PyEval_SetAsyncGenFinalizer(PyObject * finalizer)1218 _PyEval_SetAsyncGenFinalizer(PyObject *finalizer)
1219 {
1220     if (set_async_gen_finalizer(finalizer) < 0) {
1221         PyErr_WriteUnraisable(NULL);
1222     }
1223 }
1224 
1225 
1226 static PyObject *
sys_set_asyncgen_hooks(PyObject * self,PyObject * args,PyObject * kw)1227 sys_set_asyncgen_hooks(PyObject *self, PyObject *args, PyObject *kw)
1228 {
1229     static char *keywords[] = {"firstiter", "finalizer", NULL};
1230     PyObject *firstiter = NULL;
1231     PyObject *finalizer = NULL;
1232 
1233     if (!PyArg_ParseTupleAndKeywords(
1234             args, kw, "|OO", keywords,
1235             &firstiter, &finalizer)) {
1236         return NULL;
1237     }
1238 
1239     if (finalizer && finalizer != Py_None) {
1240         if (!PyCallable_Check(finalizer)) {
1241             PyErr_Format(PyExc_TypeError,
1242                          "callable finalizer expected, got %.50s",
1243                          Py_TYPE(finalizer)->tp_name);
1244             return NULL;
1245         }
1246         if (set_async_gen_finalizer(finalizer) < 0) {
1247             return NULL;
1248         }
1249     }
1250     else if (finalizer == Py_None && set_async_gen_finalizer(NULL) < 0) {
1251         return NULL;
1252     }
1253 
1254     if (firstiter && firstiter != Py_None) {
1255         if (!PyCallable_Check(firstiter)) {
1256             PyErr_Format(PyExc_TypeError,
1257                          "callable firstiter expected, got %.50s",
1258                          Py_TYPE(firstiter)->tp_name);
1259             return NULL;
1260         }
1261         if (set_async_gen_firstiter(firstiter) < 0) {
1262             return NULL;
1263         }
1264     }
1265     else if (firstiter == Py_None && set_async_gen_firstiter(NULL) < 0) {
1266         return NULL;
1267     }
1268 
1269     Py_RETURN_NONE;
1270 }
1271 
1272 PyDoc_STRVAR(set_asyncgen_hooks_doc,
1273 "set_asyncgen_hooks(* [, firstiter] [, finalizer])\n\
1274 \n\
1275 Set a finalizer for async generators objects."
1276 );
1277 
1278 /*[clinic input]
1279 sys.get_asyncgen_hooks
1280 
1281 Return the installed asynchronous generators hooks.
1282 
1283 This returns a namedtuple of the form (firstiter, finalizer).
1284 [clinic start generated code]*/
1285 
1286 static PyObject *
sys_get_asyncgen_hooks_impl(PyObject * module)1287 sys_get_asyncgen_hooks_impl(PyObject *module)
1288 /*[clinic end generated code: output=53a253707146f6cf input=3676b9ea62b14625]*/
1289 {
1290     PyObject *res;
1291     PyObject *firstiter = _PyEval_GetAsyncGenFirstiter();
1292     PyObject *finalizer = _PyEval_GetAsyncGenFinalizer();
1293 
1294     res = PyStructSequence_New(&AsyncGenHooksType);
1295     if (res == NULL) {
1296         return NULL;
1297     }
1298 
1299     if (firstiter == NULL) {
1300         firstiter = Py_None;
1301     }
1302 
1303     if (finalizer == NULL) {
1304         finalizer = Py_None;
1305     }
1306 
1307     Py_INCREF(firstiter);
1308     PyStructSequence_SET_ITEM(res, 0, firstiter);
1309 
1310     Py_INCREF(finalizer);
1311     PyStructSequence_SET_ITEM(res, 1, finalizer);
1312 
1313     return res;
1314 }
1315 
1316 
1317 static PyTypeObject Hash_InfoType;
1318 
1319 PyDoc_STRVAR(hash_info_doc,
1320 "hash_info\n\
1321 \n\
1322 A named tuple providing parameters used for computing\n\
1323 hashes. The attributes are read only.");
1324 
1325 static PyStructSequence_Field hash_info_fields[] = {
1326     {"width", "width of the type used for hashing, in bits"},
1327     {"modulus", "prime number giving the modulus on which the hash "
1328                 "function is based"},
1329     {"inf", "value to be used for hash of a positive infinity"},
1330     {"nan", "value to be used for hash of a nan"},
1331     {"imag", "multiplier used for the imaginary part of a complex number"},
1332     {"algorithm", "name of the algorithm for hashing of str, bytes and "
1333                   "memoryviews"},
1334     {"hash_bits", "internal output size of hash algorithm"},
1335     {"seed_bits", "seed size of hash algorithm"},
1336     {"cutoff", "small string optimization cutoff"},
1337     {NULL, NULL}
1338 };
1339 
1340 static PyStructSequence_Desc hash_info_desc = {
1341     "sys.hash_info",
1342     hash_info_doc,
1343     hash_info_fields,
1344     9,
1345 };
1346 
1347 static PyObject *
get_hash_info(void)1348 get_hash_info(void)
1349 {
1350     PyObject *hash_info;
1351     int field = 0;
1352     PyHash_FuncDef *hashfunc;
1353     hash_info = PyStructSequence_New(&Hash_InfoType);
1354     if (hash_info == NULL)
1355         return NULL;
1356     hashfunc = PyHash_GetFuncDef();
1357     PyStructSequence_SET_ITEM(hash_info, field++,
1358                               PyLong_FromLong(8*sizeof(Py_hash_t)));
1359     PyStructSequence_SET_ITEM(hash_info, field++,
1360                               PyLong_FromSsize_t(_PyHASH_MODULUS));
1361     PyStructSequence_SET_ITEM(hash_info, field++,
1362                               PyLong_FromLong(_PyHASH_INF));
1363     PyStructSequence_SET_ITEM(hash_info, field++,
1364                               PyLong_FromLong(_PyHASH_NAN));
1365     PyStructSequence_SET_ITEM(hash_info, field++,
1366                               PyLong_FromLong(_PyHASH_IMAG));
1367     PyStructSequence_SET_ITEM(hash_info, field++,
1368                               PyUnicode_FromString(hashfunc->name));
1369     PyStructSequence_SET_ITEM(hash_info, field++,
1370                               PyLong_FromLong(hashfunc->hash_bits));
1371     PyStructSequence_SET_ITEM(hash_info, field++,
1372                               PyLong_FromLong(hashfunc->seed_bits));
1373     PyStructSequence_SET_ITEM(hash_info, field++,
1374                               PyLong_FromLong(Py_HASH_CUTOFF));
1375     if (PyErr_Occurred()) {
1376         Py_CLEAR(hash_info);
1377         return NULL;
1378     }
1379     return hash_info;
1380 }
1381 /*[clinic input]
1382 sys.getrecursionlimit
1383 
1384 Return the current value of the recursion limit.
1385 
1386 The recursion limit is the maximum depth of the Python interpreter
1387 stack.  This limit prevents infinite recursion from causing an overflow
1388 of the C stack and crashing Python.
1389 [clinic start generated code]*/
1390 
1391 static PyObject *
sys_getrecursionlimit_impl(PyObject * module)1392 sys_getrecursionlimit_impl(PyObject *module)
1393 /*[clinic end generated code: output=d571fb6b4549ef2e input=1c6129fd2efaeea8]*/
1394 {
1395     return PyLong_FromLong(Py_GetRecursionLimit());
1396 }
1397 
1398 #ifdef MS_WINDOWS
1399 
1400 static PyTypeObject WindowsVersionType = {0, 0, 0, 0, 0, 0};
1401 
1402 static PyStructSequence_Field windows_version_fields[] = {
1403     {"major", "Major version number"},
1404     {"minor", "Minor version number"},
1405     {"build", "Build number"},
1406     {"platform", "Operating system platform"},
1407     {"service_pack", "Latest Service Pack installed on the system"},
1408     {"service_pack_major", "Service Pack major version number"},
1409     {"service_pack_minor", "Service Pack minor version number"},
1410     {"suite_mask", "Bit mask identifying available product suites"},
1411     {"product_type", "System product type"},
1412     {"platform_version", "Diagnostic version number"},
1413     {0}
1414 };
1415 
1416 static PyStructSequence_Desc windows_version_desc = {
1417     "sys.getwindowsversion",       /* name */
1418     sys_getwindowsversion__doc__,  /* doc */
1419     windows_version_fields,        /* fields */
1420     5                              /* For backward compatibility,
1421                                       only the first 5 items are accessible
1422                                       via indexing, the rest are name only */
1423 };
1424 
1425 /* Disable deprecation warnings about GetVersionEx as the result is
1426    being passed straight through to the caller, who is responsible for
1427    using it correctly. */
1428 #pragma warning(push)
1429 #pragma warning(disable:4996)
1430 
1431 /*[clinic input]
1432 sys.getwindowsversion
1433 
1434 Return info about the running version of Windows as a named tuple.
1435 
1436 The members are named: major, minor, build, platform, service_pack,
1437 service_pack_major, service_pack_minor, suite_mask, product_type and
1438 platform_version. For backward compatibility, only the first 5 items
1439 are available by indexing. All elements are numbers, except
1440 service_pack and platform_type which are strings, and platform_version
1441 which is a 3-tuple. Platform is always 2. Product_type may be 1 for a
1442 workstation, 2 for a domain controller, 3 for a server.
1443 Platform_version is a 3-tuple containing a version number that is
1444 intended for identifying the OS rather than feature detection.
1445 [clinic start generated code]*/
1446 
1447 static PyObject *
sys_getwindowsversion_impl(PyObject * module)1448 sys_getwindowsversion_impl(PyObject *module)
1449 /*[clinic end generated code: output=1ec063280b932857 input=73a228a328fee63a]*/
1450 {
1451     PyObject *version;
1452     int pos = 0;
1453     OSVERSIONINFOEXW ver;
1454     DWORD realMajor, realMinor, realBuild;
1455     HANDLE hKernel32;
1456     wchar_t kernel32_path[MAX_PATH];
1457     LPVOID verblock;
1458     DWORD verblock_size;
1459 
1460     ver.dwOSVersionInfoSize = sizeof(ver);
1461     if (!GetVersionExW((OSVERSIONINFOW*) &ver))
1462         return PyErr_SetFromWindowsErr(0);
1463 
1464     version = PyStructSequence_New(&WindowsVersionType);
1465     if (version == NULL)
1466         return NULL;
1467 
1468     PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMajorVersion));
1469     PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMinorVersion));
1470     PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwBuildNumber));
1471     PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwPlatformId));
1472     PyStructSequence_SET_ITEM(version, pos++, PyUnicode_FromWideChar(ver.szCSDVersion, -1));
1473     PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMajor));
1474     PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMinor));
1475     PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wSuiteMask));
1476     PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wProductType));
1477 
1478     realMajor = ver.dwMajorVersion;
1479     realMinor = ver.dwMinorVersion;
1480     realBuild = ver.dwBuildNumber;
1481 
1482     // GetVersion will lie if we are running in a compatibility mode.
1483     // We need to read the version info from a system file resource
1484     // to accurately identify the OS version. If we fail for any reason,
1485     // just return whatever GetVersion said.
1486     Py_BEGIN_ALLOW_THREADS
1487     hKernel32 = GetModuleHandleW(L"kernel32.dll");
1488     Py_END_ALLOW_THREADS
1489     if (hKernel32 && GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH) &&
1490         (verblock_size = GetFileVersionInfoSizeW(kernel32_path, NULL)) &&
1491         (verblock = PyMem_RawMalloc(verblock_size))) {
1492         VS_FIXEDFILEINFO *ffi;
1493         UINT ffi_len;
1494 
1495         if (GetFileVersionInfoW(kernel32_path, 0, verblock_size, verblock) &&
1496             VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) {
1497             realMajor = HIWORD(ffi->dwProductVersionMS);
1498             realMinor = LOWORD(ffi->dwProductVersionMS);
1499             realBuild = HIWORD(ffi->dwProductVersionLS);
1500         }
1501         PyMem_RawFree(verblock);
1502     }
1503     PyStructSequence_SET_ITEM(version, pos++, Py_BuildValue("(kkk)",
1504         realMajor,
1505         realMinor,
1506         realBuild
1507     ));
1508 
1509     if (PyErr_Occurred()) {
1510         Py_DECREF(version);
1511         return NULL;
1512     }
1513 
1514     return version;
1515 }
1516 
1517 #pragma warning(pop)
1518 
1519 /*[clinic input]
1520 sys._enablelegacywindowsfsencoding
1521 
1522 Changes the default filesystem encoding to mbcs:replace.
1523 
1524 This is done for consistency with earlier versions of Python. See PEP
1525 529 for more information.
1526 
1527 This is equivalent to defining the PYTHONLEGACYWINDOWSFSENCODING
1528 environment variable before launching Python.
1529 [clinic start generated code]*/
1530 
1531 static PyObject *
sys__enablelegacywindowsfsencoding_impl(PyObject * module)1532 sys__enablelegacywindowsfsencoding_impl(PyObject *module)
1533 /*[clinic end generated code: output=f5c3855b45e24fe9 input=2bfa931a20704492]*/
1534 {
1535     if (_PyUnicode_EnableLegacyWindowsFSEncoding() < 0) {
1536         return NULL;
1537     }
1538     Py_RETURN_NONE;
1539 }
1540 
1541 #endif /* MS_WINDOWS */
1542 
1543 #ifdef HAVE_DLOPEN
1544 
1545 /*[clinic input]
1546 sys.setdlopenflags
1547 
1548     flags as new_val: int
1549     /
1550 
1551 Set the flags used by the interpreter for dlopen calls.
1552 
1553 This is used, for example, when the interpreter loads extension
1554 modules. Among other things, this will enable a lazy resolving of
1555 symbols when importing a module, if called as sys.setdlopenflags(0).
1556 To share symbols across extension modules, call as
1557 sys.setdlopenflags(os.RTLD_GLOBAL).  Symbolic names for the flag
1558 modules can be found in the os module (RTLD_xxx constants, e.g.
1559 os.RTLD_LAZY).
1560 [clinic start generated code]*/
1561 
1562 static PyObject *
sys_setdlopenflags_impl(PyObject * module,int new_val)1563 sys_setdlopenflags_impl(PyObject *module, int new_val)
1564 /*[clinic end generated code: output=ec918b7fe0a37281 input=4c838211e857a77f]*/
1565 {
1566     PyInterpreterState *interp = _PyInterpreterState_Get();
1567     interp->dlopenflags = new_val;
1568     Py_RETURN_NONE;
1569 }
1570 
1571 
1572 /*[clinic input]
1573 sys.getdlopenflags
1574 
1575 Return the current value of the flags that are used for dlopen calls.
1576 
1577 The flag constants are defined in the os module.
1578 [clinic start generated code]*/
1579 
1580 static PyObject *
sys_getdlopenflags_impl(PyObject * module)1581 sys_getdlopenflags_impl(PyObject *module)
1582 /*[clinic end generated code: output=e92cd1bc5005da6e input=dc4ea0899c53b4b6]*/
1583 {
1584     PyInterpreterState *interp = _PyInterpreterState_Get();
1585     return PyLong_FromLong(interp->dlopenflags);
1586 }
1587 
1588 #endif  /* HAVE_DLOPEN */
1589 
1590 #ifdef USE_MALLOPT
1591 /* Link with -lmalloc (or -lmpc) on an SGI */
1592 #include <malloc.h>
1593 
1594 /*[clinic input]
1595 sys.mdebug
1596 
1597     flag: int
1598     /
1599 [clinic start generated code]*/
1600 
1601 static PyObject *
sys_mdebug_impl(PyObject * module,int flag)1602 sys_mdebug_impl(PyObject *module, int flag)
1603 /*[clinic end generated code: output=5431d545847c3637 input=151d150ae1636f8a]*/
1604 {
1605     int flag;
1606     mallopt(M_DEBUG, flag);
1607     Py_RETURN_NONE;
1608 }
1609 #endif /* USE_MALLOPT */
1610 
1611 size_t
_PySys_GetSizeOf(PyObject * o)1612 _PySys_GetSizeOf(PyObject *o)
1613 {
1614     PyObject *res = NULL;
1615     PyObject *method;
1616     Py_ssize_t size;
1617 
1618     /* Make sure the type is initialized. float gets initialized late */
1619     if (PyType_Ready(Py_TYPE(o)) < 0)
1620         return (size_t)-1;
1621 
1622     method = _PyObject_LookupSpecial(o, &PyId___sizeof__);
1623     if (method == NULL) {
1624         if (!PyErr_Occurred())
1625             PyErr_Format(PyExc_TypeError,
1626                          "Type %.100s doesn't define __sizeof__",
1627                          Py_TYPE(o)->tp_name);
1628     }
1629     else {
1630         res = _PyObject_CallNoArg(method);
1631         Py_DECREF(method);
1632     }
1633 
1634     if (res == NULL)
1635         return (size_t)-1;
1636 
1637     size = PyLong_AsSsize_t(res);
1638     Py_DECREF(res);
1639     if (size == -1 && PyErr_Occurred())
1640         return (size_t)-1;
1641 
1642     if (size < 0) {
1643         PyErr_SetString(PyExc_ValueError, "__sizeof__() should return >= 0");
1644         return (size_t)-1;
1645     }
1646 
1647     /* add gc_head size */
1648     if (PyObject_IS_GC(o))
1649         return ((size_t)size) + sizeof(PyGC_Head);
1650     return (size_t)size;
1651 }
1652 
1653 static PyObject *
sys_getsizeof(PyObject * self,PyObject * args,PyObject * kwds)1654 sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
1655 {
1656     static char *kwlist[] = {"object", "default", 0};
1657     size_t size;
1658     PyObject *o, *dflt = NULL;
1659 
1660     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof",
1661                                      kwlist, &o, &dflt))
1662         return NULL;
1663 
1664     size = _PySys_GetSizeOf(o);
1665 
1666     if (size == (size_t)-1 && PyErr_Occurred()) {
1667         /* Has a default value been given */
1668         if (dflt != NULL && PyErr_ExceptionMatches(PyExc_TypeError)) {
1669             PyErr_Clear();
1670             Py_INCREF(dflt);
1671             return dflt;
1672         }
1673         else
1674             return NULL;
1675     }
1676 
1677     return PyLong_FromSize_t(size);
1678 }
1679 
1680 PyDoc_STRVAR(getsizeof_doc,
1681 "getsizeof(object [, default]) -> int\n\
1682 \n\
1683 Return the size of object in bytes.");
1684 
1685 /*[clinic input]
1686 sys.getrefcount -> Py_ssize_t
1687 
1688     object:  object
1689     /
1690 
1691 Return the reference count of object.
1692 
1693 The count returned is generally one higher than you might expect,
1694 because it includes the (temporary) reference as an argument to
1695 getrefcount().
1696 [clinic start generated code]*/
1697 
1698 static Py_ssize_t
sys_getrefcount_impl(PyObject * module,PyObject * object)1699 sys_getrefcount_impl(PyObject *module, PyObject *object)
1700 /*[clinic end generated code: output=5fd477f2264b85b2 input=bf474efd50a21535]*/
1701 {
1702     return object->ob_refcnt;
1703 }
1704 
1705 #ifdef Py_REF_DEBUG
1706 /*[clinic input]
1707 sys.gettotalrefcount -> Py_ssize_t
1708 [clinic start generated code]*/
1709 
1710 static Py_ssize_t
sys_gettotalrefcount_impl(PyObject * module)1711 sys_gettotalrefcount_impl(PyObject *module)
1712 /*[clinic end generated code: output=4103886cf17c25bc input=53b744faa5d2e4f6]*/
1713 {
1714     return _Py_GetRefTotal();
1715 }
1716 #endif /* Py_REF_DEBUG */
1717 
1718 /*[clinic input]
1719 sys.getallocatedblocks -> Py_ssize_t
1720 
1721 Return the number of memory blocks currently allocated.
1722 [clinic start generated code]*/
1723 
1724 static Py_ssize_t
sys_getallocatedblocks_impl(PyObject * module)1725 sys_getallocatedblocks_impl(PyObject *module)
1726 /*[clinic end generated code: output=f0c4e873f0b6dcf7 input=dab13ee346a0673e]*/
1727 {
1728     return _Py_GetAllocatedBlocks();
1729 }
1730 
1731 #ifdef COUNT_ALLOCS
1732 /*[clinic input]
1733 sys.getcounts
1734 [clinic start generated code]*/
1735 
1736 static PyObject *
sys_getcounts_impl(PyObject * module)1737 sys_getcounts_impl(PyObject *module)
1738 /*[clinic end generated code: output=20df00bc164f43cb input=ad2ec7bda5424953]*/
1739 {
1740     extern PyObject *_Py_get_counts(void);
1741 
1742     return _Py_get_counts();
1743 }
1744 #endif
1745 
1746 /*[clinic input]
1747 sys._getframe
1748 
1749     depth: int = 0
1750     /
1751 
1752 Return a frame object from the call stack.
1753 
1754 If optional integer depth is given, return the frame object that many
1755 calls below the top of the stack.  If that is deeper than the call
1756 stack, ValueError is raised.  The default for depth is zero, returning
1757 the frame at the top of the call stack.
1758 
1759 This function should be used for internal and specialized purposes
1760 only.
1761 [clinic start generated code]*/
1762 
1763 static PyObject *
sys__getframe_impl(PyObject * module,int depth)1764 sys__getframe_impl(PyObject *module, int depth)
1765 /*[clinic end generated code: output=d438776c04d59804 input=c1be8a6464b11ee5]*/
1766 {
1767     PyFrameObject *f = _PyThreadState_GET()->frame;
1768 
1769     if (PySys_Audit("sys._getframe", "O", f) < 0) {
1770         return NULL;
1771     }
1772 
1773     while (depth > 0 && f != NULL) {
1774         f = f->f_back;
1775         --depth;
1776     }
1777     if (f == NULL) {
1778         PyErr_SetString(PyExc_ValueError,
1779                         "call stack is not deep enough");
1780         return NULL;
1781     }
1782     Py_INCREF(f);
1783     return (PyObject*)f;
1784 }
1785 
1786 /*[clinic input]
1787 sys._current_frames
1788 
1789 Return a dict mapping each thread's thread id to its current stack frame.
1790 
1791 This function should be used for specialized purposes only.
1792 [clinic start generated code]*/
1793 
1794 static PyObject *
sys__current_frames_impl(PyObject * module)1795 sys__current_frames_impl(PyObject *module)
1796 /*[clinic end generated code: output=d2a41ac0a0a3809a input=2a9049c5f5033691]*/
1797 {
1798     return _PyThread_CurrentFrames();
1799 }
1800 
1801 /*[clinic input]
1802 sys.call_tracing
1803 
1804     func: object
1805     args as funcargs: object(subclass_of='&PyTuple_Type')
1806     /
1807 
1808 Call func(*args), while tracing is enabled.
1809 
1810 The tracing state is saved, and restored afterwards.  This is intended
1811 to be called from a debugger from a checkpoint, to recursively debug
1812 some other code.
1813 [clinic start generated code]*/
1814 
1815 static PyObject *
sys_call_tracing_impl(PyObject * module,PyObject * func,PyObject * funcargs)1816 sys_call_tracing_impl(PyObject *module, PyObject *func, PyObject *funcargs)
1817 /*[clinic end generated code: output=7e4999853cd4e5a6 input=5102e8b11049f92f]*/
1818 {
1819     return _PyEval_CallTracing(func, funcargs);
1820 }
1821 
1822 /*[clinic input]
1823 sys.callstats
1824 
1825 Return a tuple of function call statistics.
1826 
1827 A tuple is returned only if CALL_PROFILE was defined when Python was
1828 built.  Otherwise, this returns None.
1829 
1830 When enabled, this function returns detailed, implementation-specific
1831 details about the number of function calls executed. The return value
1832 is a 11-tuple where the entries in the tuple are counts of:
1833 0. all function calls
1834 1. calls to PyFunction_Type objects
1835 2. PyFunction calls that do not create an argument tuple
1836 3. PyFunction calls that do not create an argument tuple
1837    and bypass PyEval_EvalCodeEx()
1838 4. PyMethod calls
1839 5. PyMethod calls on bound methods
1840 6. PyType calls
1841 7. PyCFunction calls
1842 8. generator calls
1843 9. All other calls
1844 10. Number of stack pops performed by call_function()
1845 [clinic start generated code]*/
1846 
1847 static PyObject *
sys_callstats_impl(PyObject * module)1848 sys_callstats_impl(PyObject *module)
1849 /*[clinic end generated code: output=edc4a74957fa8def input=d447d8d224d5d175]*/
1850 {
1851     if (PyErr_WarnEx(PyExc_DeprecationWarning,
1852                       "sys.callstats() has been deprecated in Python 3.7 "
1853                       "and will be removed in the future", 1) < 0) {
1854         return NULL;
1855     }
1856 
1857     Py_RETURN_NONE;
1858 }
1859 
1860 
1861 #ifdef __cplusplus
1862 extern "C" {
1863 #endif
1864 
1865 /*[clinic input]
1866 sys._debugmallocstats
1867 
1868 Print summary info to stderr about the state of pymalloc's structures.
1869 
1870 In Py_DEBUG mode, also perform some expensive internal consistency
1871 checks.
1872 [clinic start generated code]*/
1873 
1874 static PyObject *
sys__debugmallocstats_impl(PyObject * module)1875 sys__debugmallocstats_impl(PyObject *module)
1876 /*[clinic end generated code: output=ec3565f8c7cee46a input=33c0c9c416f98424]*/
1877 {
1878 #ifdef WITH_PYMALLOC
1879     if (_PyObject_DebugMallocStats(stderr)) {
1880         fputc('\n', stderr);
1881     }
1882 #endif
1883     _PyObject_DebugTypeStats(stderr);
1884 
1885     Py_RETURN_NONE;
1886 }
1887 
1888 #ifdef Py_TRACE_REFS
1889 /* Defined in objects.c because it uses static globals if that file */
1890 extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
1891 #endif
1892 
1893 #ifdef DYNAMIC_EXECUTION_PROFILE
1894 /* Defined in ceval.c because it uses static globals if that file */
1895 extern PyObject *_Py_GetDXProfile(PyObject *,  PyObject *);
1896 #endif
1897 
1898 #ifdef __cplusplus
1899 }
1900 #endif
1901 
1902 
1903 /*[clinic input]
1904 sys._clear_type_cache
1905 
1906 Clear the internal type lookup cache.
1907 [clinic start generated code]*/
1908 
1909 static PyObject *
sys__clear_type_cache_impl(PyObject * module)1910 sys__clear_type_cache_impl(PyObject *module)
1911 /*[clinic end generated code: output=20e48ca54a6f6971 input=127f3e04a8d9b555]*/
1912 {
1913     PyType_ClearCache();
1914     Py_RETURN_NONE;
1915 }
1916 
1917 /*[clinic input]
1918 sys.is_finalizing
1919 
1920 Return True if Python is exiting.
1921 [clinic start generated code]*/
1922 
1923 static PyObject *
sys_is_finalizing_impl(PyObject * module)1924 sys_is_finalizing_impl(PyObject *module)
1925 /*[clinic end generated code: output=735b5ff7962ab281 input=f0df747a039948a5]*/
1926 {
1927     return PyBool_FromLong(_Py_IsFinalizing());
1928 }
1929 
1930 #ifdef ANDROID_API_LEVEL
1931 /*[clinic input]
1932 sys.getandroidapilevel
1933 
1934 Return the build time API version of Android as an integer.
1935 [clinic start generated code]*/
1936 
1937 static PyObject *
sys_getandroidapilevel_impl(PyObject * module)1938 sys_getandroidapilevel_impl(PyObject *module)
1939 /*[clinic end generated code: output=214abf183a1c70c1 input=3e6d6c9fcdd24ac6]*/
1940 {
1941     return PyLong_FromLong(ANDROID_API_LEVEL);
1942 }
1943 #endif   /* ANDROID_API_LEVEL */
1944 
1945 
1946 
1947 static PyMethodDef sys_methods[] = {
1948     /* Might as well keep this in alphabetic order */
1949     SYS_ADDAUDITHOOK_METHODDEF
1950     {"audit",           (PyCFunction)(void(*)(void))sys_audit, METH_FASTCALL, audit_doc },
1951     {"breakpointhook",  (PyCFunction)(void(*)(void))sys_breakpointhook,
1952      METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc},
1953     SYS_CALLSTATS_METHODDEF
1954     SYS__CLEAR_TYPE_CACHE_METHODDEF
1955     SYS__CURRENT_FRAMES_METHODDEF
1956     SYS_DISPLAYHOOK_METHODDEF
1957     SYS_EXC_INFO_METHODDEF
1958     SYS_EXCEPTHOOK_METHODDEF
1959     SYS_EXIT_METHODDEF
1960     SYS_GETDEFAULTENCODING_METHODDEF
1961     SYS_GETDLOPENFLAGS_METHODDEF
1962     SYS_GETALLOCATEDBLOCKS_METHODDEF
1963     SYS_GETCOUNTS_METHODDEF
1964 #ifdef DYNAMIC_EXECUTION_PROFILE
1965     {"getdxp",          _Py_GetDXProfile, METH_VARARGS},
1966 #endif
1967     SYS_GETFILESYSTEMENCODING_METHODDEF
1968     SYS_GETFILESYSTEMENCODEERRORS_METHODDEF
1969 #ifdef Py_TRACE_REFS
1970     {"getobjects",      _Py_GetObjects, METH_VARARGS},
1971 #endif
1972     SYS_GETTOTALREFCOUNT_METHODDEF
1973     SYS_GETREFCOUNT_METHODDEF
1974     SYS_GETRECURSIONLIMIT_METHODDEF
1975     {"getsizeof",   (PyCFunction)(void(*)(void))sys_getsizeof,
1976      METH_VARARGS | METH_KEYWORDS, getsizeof_doc},
1977     SYS__GETFRAME_METHODDEF
1978     SYS_GETWINDOWSVERSION_METHODDEF
1979     SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF
1980     SYS_INTERN_METHODDEF
1981     SYS_IS_FINALIZING_METHODDEF
1982     SYS_MDEBUG_METHODDEF
1983     SYS_SETCHECKINTERVAL_METHODDEF
1984     SYS_GETCHECKINTERVAL_METHODDEF
1985     SYS_SETSWITCHINTERVAL_METHODDEF
1986     SYS_GETSWITCHINTERVAL_METHODDEF
1987     SYS_SETDLOPENFLAGS_METHODDEF
1988     {"setprofile",      sys_setprofile, METH_O, setprofile_doc},
1989     SYS_GETPROFILE_METHODDEF
1990     SYS_SETRECURSIONLIMIT_METHODDEF
1991     {"settrace",        sys_settrace, METH_O, settrace_doc},
1992     SYS_GETTRACE_METHODDEF
1993     SYS_CALL_TRACING_METHODDEF
1994     SYS__DEBUGMALLOCSTATS_METHODDEF
1995     SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF
1996     SYS_GET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF
1997     {"set_asyncgen_hooks", (PyCFunction)(void(*)(void))sys_set_asyncgen_hooks,
1998      METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc},
1999     SYS_GET_ASYNCGEN_HOOKS_METHODDEF
2000     SYS_GETANDROIDAPILEVEL_METHODDEF
2001     SYS_UNRAISABLEHOOK_METHODDEF
2002     {NULL,              NULL}           /* sentinel */
2003 };
2004 
2005 static PyObject *
list_builtin_module_names(void)2006 list_builtin_module_names(void)
2007 {
2008     PyObject *list = PyList_New(0);
2009     int i;
2010     if (list == NULL)
2011         return NULL;
2012     for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
2013         PyObject *name = PyUnicode_FromString(
2014             PyImport_Inittab[i].name);
2015         if (name == NULL)
2016             break;
2017         PyList_Append(list, name);
2018         Py_DECREF(name);
2019     }
2020     if (PyList_Sort(list) != 0) {
2021         Py_DECREF(list);
2022         list = NULL;
2023     }
2024     if (list) {
2025         PyObject *v = PyList_AsTuple(list);
2026         Py_DECREF(list);
2027         list = v;
2028     }
2029     return list;
2030 }
2031 
2032 /* Pre-initialization support for sys.warnoptions and sys._xoptions
2033  *
2034  * Modern internal code paths:
2035  *   These APIs get called after _Py_InitializeCore and get to use the
2036  *   regular CPython list, dict, and unicode APIs.
2037  *
2038  * Legacy embedding code paths:
2039  *   The multi-phase initialization API isn't public yet, so embedding
2040  *   apps still need to be able configure sys.warnoptions and sys._xoptions
2041  *   before they call Py_Initialize. To support this, we stash copies of
2042  *   the supplied wchar * sequences in linked lists, and then migrate the
2043  *   contents of those lists to the sys module in _PyInitializeCore.
2044  *
2045  */
2046 
2047 struct _preinit_entry {
2048     wchar_t *value;
2049     struct _preinit_entry *next;
2050 };
2051 
2052 typedef struct _preinit_entry *_Py_PreInitEntry;
2053 
2054 static _Py_PreInitEntry _preinit_warnoptions = NULL;
2055 static _Py_PreInitEntry _preinit_xoptions = NULL;
2056 
2057 static _Py_PreInitEntry
_alloc_preinit_entry(const wchar_t * value)2058 _alloc_preinit_entry(const wchar_t *value)
2059 {
2060     /* To get this to work, we have to initialize the runtime implicitly */
2061     _PyRuntime_Initialize();
2062 
2063     /* Force default allocator, so we can ensure that it also gets used to
2064      * destroy the linked list in _clear_preinit_entries.
2065      */
2066     PyMemAllocatorEx old_alloc;
2067     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2068 
2069     _Py_PreInitEntry node = PyMem_RawCalloc(1, sizeof(*node));
2070     if (node != NULL) {
2071         node->value = _PyMem_RawWcsdup(value);
2072         if (node->value == NULL) {
2073             PyMem_RawFree(node);
2074             node = NULL;
2075         };
2076     };
2077 
2078     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2079     return node;
2080 }
2081 
2082 static int
_append_preinit_entry(_Py_PreInitEntry * optionlist,const wchar_t * value)2083 _append_preinit_entry(_Py_PreInitEntry *optionlist, const wchar_t *value)
2084 {
2085     _Py_PreInitEntry new_entry = _alloc_preinit_entry(value);
2086     if (new_entry == NULL) {
2087         return -1;
2088     }
2089     /* We maintain the linked list in this order so it's easy to play back
2090      * the add commands in the same order later on in _Py_InitializeCore
2091      */
2092     _Py_PreInitEntry last_entry = *optionlist;
2093     if (last_entry == NULL) {
2094         *optionlist = new_entry;
2095     } else {
2096         while (last_entry->next != NULL) {
2097             last_entry = last_entry->next;
2098         }
2099         last_entry->next = new_entry;
2100     }
2101     return 0;
2102 }
2103 
2104 static void
_clear_preinit_entries(_Py_PreInitEntry * optionlist)2105 _clear_preinit_entries(_Py_PreInitEntry *optionlist)
2106 {
2107     _Py_PreInitEntry current = *optionlist;
2108     *optionlist = NULL;
2109     /* Deallocate the nodes and their contents using the default allocator */
2110     PyMemAllocatorEx old_alloc;
2111     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2112     while (current != NULL) {
2113         _Py_PreInitEntry next = current->next;
2114         PyMem_RawFree(current->value);
2115         PyMem_RawFree(current);
2116         current = next;
2117     }
2118     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2119 }
2120 
2121 
2122 PyStatus
_PySys_ReadPreinitWarnOptions(PyWideStringList * options)2123 _PySys_ReadPreinitWarnOptions(PyWideStringList *options)
2124 {
2125     PyStatus status;
2126     _Py_PreInitEntry entry;
2127 
2128     for (entry = _preinit_warnoptions; entry != NULL; entry = entry->next) {
2129         status = PyWideStringList_Append(options, entry->value);
2130         if (_PyStatus_EXCEPTION(status)) {
2131             return status;
2132         }
2133     }
2134 
2135     _clear_preinit_entries(&_preinit_warnoptions);
2136     return _PyStatus_OK();
2137 }
2138 
2139 
2140 PyStatus
_PySys_ReadPreinitXOptions(PyConfig * config)2141 _PySys_ReadPreinitXOptions(PyConfig *config)
2142 {
2143     PyStatus status;
2144     _Py_PreInitEntry entry;
2145 
2146     for (entry = _preinit_xoptions; entry != NULL; entry = entry->next) {
2147         status = PyWideStringList_Append(&config->xoptions, entry->value);
2148         if (_PyStatus_EXCEPTION(status)) {
2149             return status;
2150         }
2151     }
2152 
2153     _clear_preinit_entries(&_preinit_xoptions);
2154     return _PyStatus_OK();
2155 }
2156 
2157 
2158 static PyObject *
get_warnoptions(void)2159 get_warnoptions(void)
2160 {
2161     PyObject *warnoptions = _PySys_GetObjectId(&PyId_warnoptions);
2162     if (warnoptions == NULL || !PyList_Check(warnoptions)) {
2163         /* PEP432 TODO: we can reach this if warnoptions is NULL in the main
2164         *  interpreter config. When that happens, we need to properly set
2165          * the `warnoptions` reference in the main interpreter config as well.
2166          *
2167          * For Python 3.7, we shouldn't be able to get here due to the
2168          * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit
2169          * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig
2170          * call optional for embedding applications, thus making this
2171          * reachable again.
2172          */
2173         warnoptions = PyList_New(0);
2174         if (warnoptions == NULL)
2175             return NULL;
2176         if (_PySys_SetObjectId(&PyId_warnoptions, warnoptions)) {
2177             Py_DECREF(warnoptions);
2178             return NULL;
2179         }
2180         Py_DECREF(warnoptions);
2181     }
2182     return warnoptions;
2183 }
2184 
2185 void
PySys_ResetWarnOptions(void)2186 PySys_ResetWarnOptions(void)
2187 {
2188     PyThreadState *tstate = _PyThreadState_GET();
2189     if (tstate == NULL) {
2190         _clear_preinit_entries(&_preinit_warnoptions);
2191         return;
2192     }
2193 
2194     PyObject *warnoptions = _PySys_GetObjectId(&PyId_warnoptions);
2195     if (warnoptions == NULL || !PyList_Check(warnoptions))
2196         return;
2197     PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
2198 }
2199 
2200 static int
_PySys_AddWarnOptionWithError(PyObject * option)2201 _PySys_AddWarnOptionWithError(PyObject *option)
2202 {
2203     PyObject *warnoptions = get_warnoptions();
2204     if (warnoptions == NULL) {
2205         return -1;
2206     }
2207     if (PyList_Append(warnoptions, option)) {
2208         return -1;
2209     }
2210     return 0;
2211 }
2212 
2213 void
PySys_AddWarnOptionUnicode(PyObject * option)2214 PySys_AddWarnOptionUnicode(PyObject *option)
2215 {
2216     if (_PySys_AddWarnOptionWithError(option) < 0) {
2217         /* No return value, therefore clear error state if possible */
2218         if (_PyThreadState_UncheckedGet()) {
2219             PyErr_Clear();
2220         }
2221     }
2222 }
2223 
2224 void
PySys_AddWarnOption(const wchar_t * s)2225 PySys_AddWarnOption(const wchar_t *s)
2226 {
2227     PyThreadState *tstate = _PyThreadState_GET();
2228     if (tstate == NULL) {
2229         _append_preinit_entry(&_preinit_warnoptions, s);
2230         return;
2231     }
2232     PyObject *unicode;
2233     unicode = PyUnicode_FromWideChar(s, -1);
2234     if (unicode == NULL)
2235         return;
2236     PySys_AddWarnOptionUnicode(unicode);
2237     Py_DECREF(unicode);
2238 }
2239 
2240 int
PySys_HasWarnOptions(void)2241 PySys_HasWarnOptions(void)
2242 {
2243     PyObject *warnoptions = _PySys_GetObjectId(&PyId_warnoptions);
2244     return (warnoptions != NULL && PyList_Check(warnoptions)
2245             && PyList_GET_SIZE(warnoptions) > 0);
2246 }
2247 
2248 static PyObject *
get_xoptions(void)2249 get_xoptions(void)
2250 {
2251     PyObject *xoptions = _PySys_GetObjectId(&PyId__xoptions);
2252     if (xoptions == NULL || !PyDict_Check(xoptions)) {
2253         /* PEP432 TODO: we can reach this if xoptions is NULL in the main
2254         *  interpreter config. When that happens, we need to properly set
2255          * the `xoptions` reference in the main interpreter config as well.
2256          *
2257          * For Python 3.7, we shouldn't be able to get here due to the
2258          * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit
2259          * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig
2260          * call optional for embedding applications, thus making this
2261          * reachable again.
2262          */
2263         xoptions = PyDict_New();
2264         if (xoptions == NULL)
2265             return NULL;
2266         if (_PySys_SetObjectId(&PyId__xoptions, xoptions)) {
2267             Py_DECREF(xoptions);
2268             return NULL;
2269         }
2270         Py_DECREF(xoptions);
2271     }
2272     return xoptions;
2273 }
2274 
2275 static int
_PySys_AddXOptionWithError(const wchar_t * s)2276 _PySys_AddXOptionWithError(const wchar_t *s)
2277 {
2278     PyObject *name = NULL, *value = NULL;
2279 
2280     PyObject *opts = get_xoptions();
2281     if (opts == NULL) {
2282         goto error;
2283     }
2284 
2285     const wchar_t *name_end = wcschr(s, L'=');
2286     if (!name_end) {
2287         name = PyUnicode_FromWideChar(s, -1);
2288         value = Py_True;
2289         Py_INCREF(value);
2290     }
2291     else {
2292         name = PyUnicode_FromWideChar(s, name_end - s);
2293         value = PyUnicode_FromWideChar(name_end + 1, -1);
2294     }
2295     if (name == NULL || value == NULL) {
2296         goto error;
2297     }
2298     if (PyDict_SetItem(opts, name, value) < 0) {
2299         goto error;
2300     }
2301     Py_DECREF(name);
2302     Py_DECREF(value);
2303     return 0;
2304 
2305 error:
2306     Py_XDECREF(name);
2307     Py_XDECREF(value);
2308     return -1;
2309 }
2310 
2311 void
PySys_AddXOption(const wchar_t * s)2312 PySys_AddXOption(const wchar_t *s)
2313 {
2314     PyThreadState *tstate = _PyThreadState_GET();
2315     if (tstate == NULL) {
2316         _append_preinit_entry(&_preinit_xoptions, s);
2317         return;
2318     }
2319     if (_PySys_AddXOptionWithError(s) < 0) {
2320         /* No return value, therefore clear error state if possible */
2321         PyErr_Clear();
2322     }
2323 }
2324 
2325 PyObject *
PySys_GetXOptions(void)2326 PySys_GetXOptions(void)
2327 {
2328     return get_xoptions();
2329 }
2330 
2331 /* XXX This doc string is too long to be a single string literal in VC++ 5.0.
2332    Two literals concatenated works just fine.  If you have a K&R compiler
2333    or other abomination that however *does* understand longer strings,
2334    get rid of the !!! comment in the middle and the quotes that surround it. */
2335 PyDoc_VAR(sys_doc) =
2336 PyDoc_STR(
2337 "This module provides access to some objects used or maintained by the\n\
2338 interpreter and to functions that interact strongly with the interpreter.\n\
2339 \n\
2340 Dynamic objects:\n\
2341 \n\
2342 argv -- command line arguments; argv[0] is the script pathname if known\n\
2343 path -- module search path; path[0] is the script directory, else ''\n\
2344 modules -- dictionary of loaded modules\n\
2345 \n\
2346 displayhook -- called to show results in an interactive session\n\
2347 excepthook -- called to handle any uncaught exception other than SystemExit\n\
2348   To customize printing in an interactive session or to install a custom\n\
2349   top-level exception handler, assign other functions to replace these.\n\
2350 \n\
2351 stdin -- standard input file object; used by input()\n\
2352 stdout -- standard output file object; used by print()\n\
2353 stderr -- standard error object; used for error messages\n\
2354   By assigning other file objects (or objects that behave like files)\n\
2355   to these, it is possible to redirect all of the interpreter's I/O.\n\
2356 \n\
2357 last_type -- type of last uncaught exception\n\
2358 last_value -- value of last uncaught exception\n\
2359 last_traceback -- traceback of last uncaught exception\n\
2360   These three are only available in an interactive session after a\n\
2361   traceback has been printed.\n\
2362 "
2363 )
2364 /* concatenating string here */
2365 PyDoc_STR(
2366 "\n\
2367 Static objects:\n\
2368 \n\
2369 builtin_module_names -- tuple of module names built into this interpreter\n\
2370 copyright -- copyright notice pertaining to this interpreter\n\
2371 exec_prefix -- prefix used to find the machine-specific Python library\n\
2372 executable -- absolute path of the executable binary of the Python interpreter\n\
2373 float_info -- a named tuple with information about the float implementation.\n\
2374 float_repr_style -- string indicating the style of repr() output for floats\n\
2375 hash_info -- a named tuple with information about the hash algorithm.\n\
2376 hexversion -- version information encoded as a single integer\n\
2377 implementation -- Python implementation information.\n\
2378 int_info -- a named tuple with information about the int implementation.\n\
2379 maxsize -- the largest supported length of containers.\n\
2380 maxunicode -- the value of the largest Unicode code point\n\
2381 platform -- platform identifier\n\
2382 prefix -- prefix used to find the Python library\n\
2383 thread_info -- a named tuple with information about the thread implementation.\n\
2384 version -- the version of this interpreter as a string\n\
2385 version_info -- version information as a named tuple\n\
2386 "
2387 )
2388 #ifdef MS_COREDLL
2389 /* concatenating string here */
2390 PyDoc_STR(
2391 "dllhandle -- [Windows only] integer handle of the Python DLL\n\
2392 winver -- [Windows only] version number of the Python DLL\n\
2393 "
2394 )
2395 #endif /* MS_COREDLL */
2396 #ifdef MS_WINDOWS
2397 /* concatenating string here */
2398 PyDoc_STR(
2399 "_enablelegacywindowsfsencoding -- [Windows only]\n\
2400 "
2401 )
2402 #endif
2403 PyDoc_STR(
2404 "__stdin__ -- the original stdin; don't touch!\n\
2405 __stdout__ -- the original stdout; don't touch!\n\
2406 __stderr__ -- the original stderr; don't touch!\n\
2407 __displayhook__ -- the original displayhook; don't touch!\n\
2408 __excepthook__ -- the original excepthook; don't touch!\n\
2409 \n\
2410 Functions:\n\
2411 \n\
2412 displayhook() -- print an object to the screen, and save it in builtins._\n\
2413 excepthook() -- print an exception and its traceback to sys.stderr\n\
2414 exc_info() -- return thread-safe information about the current exception\n\
2415 exit() -- exit the interpreter by raising SystemExit\n\
2416 getdlopenflags() -- returns flags to be used for dlopen() calls\n\
2417 getprofile() -- get the global profiling function\n\
2418 getrefcount() -- return the reference count for an object (plus one :-)\n\
2419 getrecursionlimit() -- return the max recursion depth for the interpreter\n\
2420 getsizeof() -- return the size of an object in bytes\n\
2421 gettrace() -- get the global debug tracing function\n\
2422 setcheckinterval() -- control how often the interpreter checks for events\n\
2423 setdlopenflags() -- set the flags to be used for dlopen() calls\n\
2424 setprofile() -- set the global profiling function\n\
2425 setrecursionlimit() -- set the max recursion depth for the interpreter\n\
2426 settrace() -- set the global debug tracing function\n\
2427 "
2428 )
2429 /* end of sys_doc */ ;
2430 
2431 
2432 PyDoc_STRVAR(flags__doc__,
2433 "sys.flags\n\
2434 \n\
2435 Flags provided through command line arguments or environment vars.");
2436 
2437 static PyTypeObject FlagsType;
2438 
2439 static PyStructSequence_Field flags_fields[] = {
2440     {"debug",                   "-d"},
2441     {"inspect",                 "-i"},
2442     {"interactive",             "-i"},
2443     {"optimize",                "-O or -OO"},
2444     {"dont_write_bytecode",     "-B"},
2445     {"no_user_site",            "-s"},
2446     {"no_site",                 "-S"},
2447     {"ignore_environment",      "-E"},
2448     {"verbose",                 "-v"},
2449     /* {"unbuffered",                   "-u"}, */
2450     /* {"skip_first",                   "-x"}, */
2451     {"bytes_warning",           "-b"},
2452     {"quiet",                   "-q"},
2453     {"hash_randomization",      "-R"},
2454     {"isolated",                "-I"},
2455     {"dev_mode",                "-X dev"},
2456     {"utf8_mode",               "-X utf8"},
2457     {0}
2458 };
2459 
2460 static PyStructSequence_Desc flags_desc = {
2461     "sys.flags",        /* name */
2462     flags__doc__,       /* doc */
2463     flags_fields,       /* fields */
2464     15
2465 };
2466 
2467 static PyObject*
make_flags(_PyRuntimeState * runtime,PyInterpreterState * interp)2468 make_flags(_PyRuntimeState *runtime, PyInterpreterState *interp)
2469 {
2470     int pos = 0;
2471     PyObject *seq;
2472     const PyPreConfig *preconfig = &runtime->preconfig;
2473     const PyConfig *config = &interp->config;
2474 
2475     seq = PyStructSequence_New(&FlagsType);
2476     if (seq == NULL)
2477         return NULL;
2478 
2479 #define SetFlag(flag) \
2480     PyStructSequence_SET_ITEM(seq, pos++, PyLong_FromLong(flag))
2481 
2482     SetFlag(config->parser_debug);
2483     SetFlag(config->inspect);
2484     SetFlag(config->interactive);
2485     SetFlag(config->optimization_level);
2486     SetFlag(!config->write_bytecode);
2487     SetFlag(!config->user_site_directory);
2488     SetFlag(!config->site_import);
2489     SetFlag(!config->use_environment);
2490     SetFlag(config->verbose);
2491     /* SetFlag(saw_unbuffered_flag); */
2492     /* SetFlag(skipfirstline); */
2493     SetFlag(config->bytes_warning);
2494     SetFlag(config->quiet);
2495     SetFlag(config->use_hash_seed == 0 || config->hash_seed != 0);
2496     SetFlag(config->isolated);
2497     PyStructSequence_SET_ITEM(seq, pos++, PyBool_FromLong(config->dev_mode));
2498     SetFlag(preconfig->utf8_mode);
2499 #undef SetFlag
2500 
2501     if (PyErr_Occurred()) {
2502         Py_DECREF(seq);
2503         return NULL;
2504     }
2505     return seq;
2506 }
2507 
2508 PyDoc_STRVAR(version_info__doc__,
2509 "sys.version_info\n\
2510 \n\
2511 Version information as a named tuple.");
2512 
2513 static PyTypeObject VersionInfoType;
2514 
2515 static PyStructSequence_Field version_info_fields[] = {
2516     {"major", "Major release number"},
2517     {"minor", "Minor release number"},
2518     {"micro", "Patch release number"},
2519     {"releaselevel", "'alpha', 'beta', 'candidate', or 'final'"},
2520     {"serial", "Serial release number"},
2521     {0}
2522 };
2523 
2524 static PyStructSequence_Desc version_info_desc = {
2525     "sys.version_info",     /* name */
2526     version_info__doc__,    /* doc */
2527     version_info_fields,    /* fields */
2528     5
2529 };
2530 
2531 static PyObject *
make_version_info(void)2532 make_version_info(void)
2533 {
2534     PyObject *version_info;
2535     char *s;
2536     int pos = 0;
2537 
2538     version_info = PyStructSequence_New(&VersionInfoType);
2539     if (version_info == NULL) {
2540         return NULL;
2541     }
2542 
2543     /*
2544      * These release level checks are mutually exclusive and cover
2545      * the field, so don't get too fancy with the pre-processor!
2546      */
2547 #if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
2548     s = "alpha";
2549 #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
2550     s = "beta";
2551 #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
2552     s = "candidate";
2553 #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
2554     s = "final";
2555 #endif
2556 
2557 #define SetIntItem(flag) \
2558     PyStructSequence_SET_ITEM(version_info, pos++, PyLong_FromLong(flag))
2559 #define SetStrItem(flag) \
2560     PyStructSequence_SET_ITEM(version_info, pos++, PyUnicode_FromString(flag))
2561 
2562     SetIntItem(PY_MAJOR_VERSION);
2563     SetIntItem(PY_MINOR_VERSION);
2564     SetIntItem(PY_MICRO_VERSION);
2565     SetStrItem(s);
2566     SetIntItem(PY_RELEASE_SERIAL);
2567 #undef SetIntItem
2568 #undef SetStrItem
2569 
2570     if (PyErr_Occurred()) {
2571         Py_CLEAR(version_info);
2572         return NULL;
2573     }
2574     return version_info;
2575 }
2576 
2577 /* sys.implementation values */
2578 #define NAME "cpython"
2579 const char *_PySys_ImplName = NAME;
2580 #define MAJOR Py_STRINGIFY(PY_MAJOR_VERSION)
2581 #define MINOR Py_STRINGIFY(PY_MINOR_VERSION)
2582 #define TAG NAME "-" MAJOR MINOR
2583 const char *_PySys_ImplCacheTag = TAG;
2584 #undef NAME
2585 #undef MAJOR
2586 #undef MINOR
2587 #undef TAG
2588 
2589 static PyObject *
make_impl_info(PyObject * version_info)2590 make_impl_info(PyObject *version_info)
2591 {
2592     int res;
2593     PyObject *impl_info, *value, *ns;
2594 
2595     impl_info = PyDict_New();
2596     if (impl_info == NULL)
2597         return NULL;
2598 
2599     /* populate the dict */
2600 
2601     value = PyUnicode_FromString(_PySys_ImplName);
2602     if (value == NULL)
2603         goto error;
2604     res = PyDict_SetItemString(impl_info, "name", value);
2605     Py_DECREF(value);
2606     if (res < 0)
2607         goto error;
2608 
2609     value = PyUnicode_FromString(_PySys_ImplCacheTag);
2610     if (value == NULL)
2611         goto error;
2612     res = PyDict_SetItemString(impl_info, "cache_tag", value);
2613     Py_DECREF(value);
2614     if (res < 0)
2615         goto error;
2616 
2617     res = PyDict_SetItemString(impl_info, "version", version_info);
2618     if (res < 0)
2619         goto error;
2620 
2621     value = PyLong_FromLong(PY_VERSION_HEX);
2622     if (value == NULL)
2623         goto error;
2624     res = PyDict_SetItemString(impl_info, "hexversion", value);
2625     Py_DECREF(value);
2626     if (res < 0)
2627         goto error;
2628 
2629 #ifdef MULTIARCH
2630     value = PyUnicode_FromString(MULTIARCH);
2631     if (value == NULL)
2632         goto error;
2633     res = PyDict_SetItemString(impl_info, "_multiarch", value);
2634     Py_DECREF(value);
2635     if (res < 0)
2636         goto error;
2637 #endif
2638 
2639     /* dict ready */
2640 
2641     ns = _PyNamespace_New(impl_info);
2642     Py_DECREF(impl_info);
2643     return ns;
2644 
2645 error:
2646     Py_CLEAR(impl_info);
2647     return NULL;
2648 }
2649 
2650 static struct PyModuleDef sysmodule = {
2651     PyModuleDef_HEAD_INIT,
2652     "sys",
2653     sys_doc,
2654     -1, /* multiple "initialization" just copies the module dict. */
2655     sys_methods,
2656     NULL,
2657     NULL,
2658     NULL,
2659     NULL
2660 };
2661 
2662 /* Updating the sys namespace, returning NULL pointer on error */
2663 #define SET_SYS_FROM_STRING_BORROW(key, value)             \
2664     do {                                                   \
2665         PyObject *v = (value);                             \
2666         if (v == NULL) {                                   \
2667             goto err_occurred;                             \
2668         }                                                  \
2669         res = PyDict_SetItemString(sysdict, key, v);       \
2670         if (res < 0) {                                     \
2671             goto err_occurred;                             \
2672         }                                                  \
2673     } while (0)
2674 #define SET_SYS_FROM_STRING(key, value)                    \
2675     do {                                                   \
2676         PyObject *v = (value);                             \
2677         if (v == NULL) {                                   \
2678             goto err_occurred;                             \
2679         }                                                  \
2680         res = PyDict_SetItemString(sysdict, key, v);       \
2681         Py_DECREF(v);                                      \
2682         if (res < 0) {                                     \
2683             goto err_occurred;                             \
2684         }                                                  \
2685     } while (0)
2686 
2687 static PyStatus
_PySys_InitCore(_PyRuntimeState * runtime,PyInterpreterState * interp,PyObject * sysdict)2688 _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp,
2689                 PyObject *sysdict)
2690 {
2691     PyObject *version_info;
2692     int res;
2693 
2694     /* stdin/stdout/stderr are set in pylifecycle.c */
2695 
2696     SET_SYS_FROM_STRING_BORROW("__displayhook__",
2697                                PyDict_GetItemString(sysdict, "displayhook"));
2698     SET_SYS_FROM_STRING_BORROW("__excepthook__",
2699                                PyDict_GetItemString(sysdict, "excepthook"));
2700     SET_SYS_FROM_STRING_BORROW(
2701         "__breakpointhook__",
2702         PyDict_GetItemString(sysdict, "breakpointhook"));
2703     SET_SYS_FROM_STRING_BORROW("__unraisablehook__",
2704                                PyDict_GetItemString(sysdict, "unraisablehook"));
2705 
2706     SET_SYS_FROM_STRING("version",
2707                          PyUnicode_FromString(Py_GetVersion()));
2708     SET_SYS_FROM_STRING("hexversion",
2709                          PyLong_FromLong(PY_VERSION_HEX));
2710     SET_SYS_FROM_STRING("_git",
2711                         Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(),
2712                                       _Py_gitversion()));
2713     SET_SYS_FROM_STRING("_framework", PyUnicode_FromString(_PYTHONFRAMEWORK));
2714     SET_SYS_FROM_STRING("api_version",
2715                         PyLong_FromLong(PYTHON_API_VERSION));
2716     SET_SYS_FROM_STRING("copyright",
2717                         PyUnicode_FromString(Py_GetCopyright()));
2718     SET_SYS_FROM_STRING("platform",
2719                         PyUnicode_FromString(Py_GetPlatform()));
2720     SET_SYS_FROM_STRING("maxsize",
2721                         PyLong_FromSsize_t(PY_SSIZE_T_MAX));
2722     SET_SYS_FROM_STRING("float_info",
2723                         PyFloat_GetInfo());
2724     SET_SYS_FROM_STRING("int_info",
2725                         PyLong_GetInfo());
2726     /* initialize hash_info */
2727     if (Hash_InfoType.tp_name == NULL) {
2728         if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0) {
2729             goto type_init_failed;
2730         }
2731     }
2732     SET_SYS_FROM_STRING("hash_info",
2733                         get_hash_info());
2734     SET_SYS_FROM_STRING("maxunicode",
2735                         PyLong_FromLong(0x10FFFF));
2736     SET_SYS_FROM_STRING("builtin_module_names",
2737                         list_builtin_module_names());
2738 #if PY_BIG_ENDIAN
2739     SET_SYS_FROM_STRING("byteorder",
2740                         PyUnicode_FromString("big"));
2741 #else
2742     SET_SYS_FROM_STRING("byteorder",
2743                         PyUnicode_FromString("little"));
2744 #endif
2745 
2746 #ifdef MS_COREDLL
2747     SET_SYS_FROM_STRING("dllhandle",
2748                         PyLong_FromVoidPtr(PyWin_DLLhModule));
2749     SET_SYS_FROM_STRING("winver",
2750                         PyUnicode_FromString(PyWin_DLLVersionString));
2751 #endif
2752 #ifdef ABIFLAGS
2753     SET_SYS_FROM_STRING("abiflags",
2754                         PyUnicode_FromString(ABIFLAGS));
2755 #endif
2756 
2757     /* version_info */
2758     if (VersionInfoType.tp_name == NULL) {
2759         if (PyStructSequence_InitType2(&VersionInfoType,
2760                                        &version_info_desc) < 0) {
2761             goto type_init_failed;
2762         }
2763     }
2764     version_info = make_version_info();
2765     SET_SYS_FROM_STRING("version_info", version_info);
2766     /* prevent user from creating new instances */
2767     VersionInfoType.tp_init = NULL;
2768     VersionInfoType.tp_new = NULL;
2769     res = PyDict_DelItemString(VersionInfoType.tp_dict, "__new__");
2770     if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
2771         PyErr_Clear();
2772 
2773     /* implementation */
2774     SET_SYS_FROM_STRING("implementation", make_impl_info(version_info));
2775 
2776     /* flags */
2777     if (FlagsType.tp_name == 0) {
2778         if (PyStructSequence_InitType2(&FlagsType, &flags_desc) < 0) {
2779             goto type_init_failed;
2780         }
2781     }
2782     /* Set flags to their default values (updated by _PySys_InitMain()) */
2783     SET_SYS_FROM_STRING("flags", make_flags(runtime, interp));
2784 
2785 #if defined(MS_WINDOWS)
2786     /* getwindowsversion */
2787     if (WindowsVersionType.tp_name == 0)
2788         if (PyStructSequence_InitType2(&WindowsVersionType,
2789                                        &windows_version_desc) < 0) {
2790             goto type_init_failed;
2791         }
2792     /* prevent user from creating new instances */
2793     WindowsVersionType.tp_init = NULL;
2794     WindowsVersionType.tp_new = NULL;
2795     assert(!PyErr_Occurred());
2796     res = PyDict_DelItemString(WindowsVersionType.tp_dict, "__new__");
2797     if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) {
2798         PyErr_Clear();
2799     }
2800 #endif
2801 
2802     /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */
2803 #ifndef PY_NO_SHORT_FLOAT_REPR
2804     SET_SYS_FROM_STRING("float_repr_style",
2805                         PyUnicode_FromString("short"));
2806 #else
2807     SET_SYS_FROM_STRING("float_repr_style",
2808                         PyUnicode_FromString("legacy"));
2809 #endif
2810 
2811     SET_SYS_FROM_STRING("thread_info", PyThread_GetInfo());
2812 
2813     /* initialize asyncgen_hooks */
2814     if (AsyncGenHooksType.tp_name == NULL) {
2815         if (PyStructSequence_InitType2(
2816                 &AsyncGenHooksType, &asyncgen_hooks_desc) < 0) {
2817             goto type_init_failed;
2818         }
2819     }
2820 
2821     if (PyErr_Occurred()) {
2822         goto err_occurred;
2823     }
2824     return _PyStatus_OK();
2825 
2826 type_init_failed:
2827     return _PyStatus_ERR("failed to initialize a type");
2828 
2829 err_occurred:
2830     return _PyStatus_ERR("can't initialize sys module");
2831 }
2832 
2833 #undef SET_SYS_FROM_STRING
2834 
2835 /* Updating the sys namespace, returning integer error codes */
2836 #define SET_SYS_FROM_STRING_INT_RESULT(key, value)         \
2837     do {                                                   \
2838         PyObject *v = (value);                             \
2839         if (v == NULL)                                     \
2840             return -1;                                     \
2841         res = PyDict_SetItemString(sysdict, key, v);       \
2842         Py_DECREF(v);                                      \
2843         if (res < 0) {                                     \
2844             return res;                                    \
2845         }                                                  \
2846     } while (0)
2847 
2848 
2849 static int
sys_add_xoption(PyObject * opts,const wchar_t * s)2850 sys_add_xoption(PyObject *opts, const wchar_t *s)
2851 {
2852     PyObject *name, *value;
2853 
2854     const wchar_t *name_end = wcschr(s, L'=');
2855     if (!name_end) {
2856         name = PyUnicode_FromWideChar(s, -1);
2857         value = Py_True;
2858         Py_INCREF(value);
2859     }
2860     else {
2861         name = PyUnicode_FromWideChar(s, name_end - s);
2862         value = PyUnicode_FromWideChar(name_end + 1, -1);
2863     }
2864     if (name == NULL || value == NULL) {
2865         goto error;
2866     }
2867     if (PyDict_SetItem(opts, name, value) < 0) {
2868         goto error;
2869     }
2870     Py_DECREF(name);
2871     Py_DECREF(value);
2872     return 0;
2873 
2874 error:
2875     Py_XDECREF(name);
2876     Py_XDECREF(value);
2877     return -1;
2878 }
2879 
2880 
2881 static PyObject*
sys_create_xoptions_dict(const PyConfig * config)2882 sys_create_xoptions_dict(const PyConfig *config)
2883 {
2884     Py_ssize_t nxoption = config->xoptions.length;
2885     wchar_t * const * xoptions = config->xoptions.items;
2886     PyObject *dict = PyDict_New();
2887     if (dict == NULL) {
2888         return NULL;
2889     }
2890 
2891     for (Py_ssize_t i=0; i < nxoption; i++) {
2892         const wchar_t *option = xoptions[i];
2893         if (sys_add_xoption(dict, option) < 0) {
2894             Py_DECREF(dict);
2895             return NULL;
2896         }
2897     }
2898 
2899     return dict;
2900 }
2901 
2902 
2903 int
_PySys_InitMain(_PyRuntimeState * runtime,PyInterpreterState * interp)2904 _PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp)
2905 {
2906     PyObject *sysdict = interp->sysdict;
2907     const PyConfig *config = &interp->config;
2908     int res;
2909 
2910 #define COPY_LIST(KEY, VALUE) \
2911     do { \
2912         PyObject *list = _PyWideStringList_AsList(&(VALUE)); \
2913         if (list == NULL) { \
2914             return -1; \
2915         } \
2916         SET_SYS_FROM_STRING_BORROW(KEY, list); \
2917         Py_DECREF(list); \
2918     } while (0)
2919 
2920 #define SET_SYS_FROM_WSTR(KEY, VALUE) \
2921     do { \
2922         PyObject *str = PyUnicode_FromWideChar(VALUE, -1); \
2923         if (str == NULL) { \
2924             return -1; \
2925         } \
2926         SET_SYS_FROM_STRING_BORROW(KEY, str); \
2927         Py_DECREF(str); \
2928     } while (0)
2929 
2930     COPY_LIST("path", config->module_search_paths);
2931 
2932     SET_SYS_FROM_WSTR("executable", config->executable);
2933     SET_SYS_FROM_WSTR("_base_executable", config->base_executable);
2934     SET_SYS_FROM_WSTR("prefix", config->prefix);
2935     SET_SYS_FROM_WSTR("base_prefix", config->base_prefix);
2936     SET_SYS_FROM_WSTR("exec_prefix", config->exec_prefix);
2937     SET_SYS_FROM_WSTR("base_exec_prefix", config->base_exec_prefix);
2938 
2939     if (config->pycache_prefix != NULL) {
2940         SET_SYS_FROM_WSTR("pycache_prefix", config->pycache_prefix);
2941     } else {
2942         PyDict_SetItemString(sysdict, "pycache_prefix", Py_None);
2943     }
2944 
2945     COPY_LIST("argv", config->argv);
2946     COPY_LIST("warnoptions", config->warnoptions);
2947 
2948     PyObject *xoptions = sys_create_xoptions_dict(config);
2949     if (xoptions == NULL) {
2950         return -1;
2951     }
2952     SET_SYS_FROM_STRING_BORROW("_xoptions", xoptions);
2953     Py_DECREF(xoptions);
2954 
2955 #undef COPY_LIST
2956 #undef SET_SYS_FROM_WSTR
2957 
2958     /* Set flags to their final values */
2959     SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(runtime, interp));
2960     /* prevent user from creating new instances */
2961     FlagsType.tp_init = NULL;
2962     FlagsType.tp_new = NULL;
2963     res = PyDict_DelItemString(FlagsType.tp_dict, "__new__");
2964     if (res < 0) {
2965         if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
2966             return res;
2967         }
2968         PyErr_Clear();
2969     }
2970 
2971     SET_SYS_FROM_STRING_INT_RESULT("dont_write_bytecode",
2972                          PyBool_FromLong(!config->write_bytecode));
2973 
2974     if (get_warnoptions() == NULL)
2975         return -1;
2976 
2977     if (get_xoptions() == NULL)
2978         return -1;
2979 
2980     if (PyErr_Occurred())
2981         return -1;
2982 
2983     return 0;
2984 
2985 err_occurred:
2986     return -1;
2987 }
2988 
2989 #undef SET_SYS_FROM_STRING_BORROW
2990 #undef SET_SYS_FROM_STRING_INT_RESULT
2991 
2992 
2993 /* Set up a preliminary stderr printer until we have enough
2994    infrastructure for the io module in place.
2995 
2996    Use UTF-8/surrogateescape and ignore EAGAIN errors. */
2997 PyStatus
_PySys_SetPreliminaryStderr(PyObject * sysdict)2998 _PySys_SetPreliminaryStderr(PyObject *sysdict)
2999 {
3000     PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr));
3001     if (pstderr == NULL) {
3002         goto error;
3003     }
3004     if (_PyDict_SetItemId(sysdict, &PyId_stderr, pstderr) < 0) {
3005         goto error;
3006     }
3007     if (PyDict_SetItemString(sysdict, "__stderr__", pstderr) < 0) {
3008         goto error;
3009     }
3010     Py_DECREF(pstderr);
3011     return _PyStatus_OK();
3012 
3013 error:
3014     Py_XDECREF(pstderr);
3015     return _PyStatus_ERR("can't set preliminary stderr");
3016 }
3017 
3018 
3019 /* Create sys module without all attributes: _PySys_InitMain() should be called
3020    later to add remaining attributes. */
3021 PyStatus
_PySys_Create(_PyRuntimeState * runtime,PyInterpreterState * interp,PyObject ** sysmod_p)3022 _PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp,
3023               PyObject **sysmod_p)
3024 {
3025     PyObject *modules = PyDict_New();
3026     if (modules == NULL) {
3027         return _PyStatus_ERR("can't make modules dictionary");
3028     }
3029     interp->modules = modules;
3030 
3031     PyObject *sysmod = _PyModule_CreateInitialized(&sysmodule, PYTHON_API_VERSION);
3032     if (sysmod == NULL) {
3033         return _PyStatus_ERR("failed to create a module object");
3034     }
3035 
3036     PyObject *sysdict = PyModule_GetDict(sysmod);
3037     if (sysdict == NULL) {
3038         return _PyStatus_ERR("can't initialize sys dict");
3039     }
3040     Py_INCREF(sysdict);
3041     interp->sysdict = sysdict;
3042 
3043     if (PyDict_SetItemString(sysdict, "modules", interp->modules) < 0) {
3044         return _PyStatus_ERR("can't initialize sys module");
3045     }
3046 
3047     PyStatus status = _PySys_SetPreliminaryStderr(sysdict);
3048     if (_PyStatus_EXCEPTION(status)) {
3049         return status;
3050     }
3051 
3052     status = _PySys_InitCore(runtime, interp, sysdict);
3053     if (_PyStatus_EXCEPTION(status)) {
3054         return status;
3055     }
3056 
3057     _PyImport_FixupBuiltin(sysmod, "sys", interp->modules);
3058 
3059     *sysmod_p = sysmod;
3060     return _PyStatus_OK();
3061 }
3062 
3063 
3064 static PyObject *
makepathobject(const wchar_t * path,wchar_t delim)3065 makepathobject(const wchar_t *path, wchar_t delim)
3066 {
3067     int i, n;
3068     const wchar_t *p;
3069     PyObject *v, *w;
3070 
3071     n = 1;
3072     p = path;
3073     while ((p = wcschr(p, delim)) != NULL) {
3074         n++;
3075         p++;
3076     }
3077     v = PyList_New(n);
3078     if (v == NULL)
3079         return NULL;
3080     for (i = 0; ; i++) {
3081         p = wcschr(path, delim);
3082         if (p == NULL)
3083             p = path + wcslen(path); /* End of string */
3084         w = PyUnicode_FromWideChar(path, (Py_ssize_t)(p - path));
3085         if (w == NULL) {
3086             Py_DECREF(v);
3087             return NULL;
3088         }
3089         PyList_SET_ITEM(v, i, w);
3090         if (*p == '\0')
3091             break;
3092         path = p+1;
3093     }
3094     return v;
3095 }
3096 
3097 void
PySys_SetPath(const wchar_t * path)3098 PySys_SetPath(const wchar_t *path)
3099 {
3100     PyObject *v;
3101     if ((v = makepathobject(path, DELIM)) == NULL)
3102         Py_FatalError("can't create sys.path");
3103     if (_PySys_SetObjectId(&PyId_path, v) != 0)
3104         Py_FatalError("can't assign sys.path");
3105     Py_DECREF(v);
3106 }
3107 
3108 static PyObject *
make_sys_argv(int argc,wchar_t * const * argv)3109 make_sys_argv(int argc, wchar_t * const * argv)
3110 {
3111     PyObject *list = PyList_New(argc);
3112     if (list == NULL) {
3113         return NULL;
3114     }
3115 
3116     for (Py_ssize_t i = 0; i < argc; i++) {
3117         PyObject *v = PyUnicode_FromWideChar(argv[i], -1);
3118         if (v == NULL) {
3119             Py_DECREF(list);
3120             return NULL;
3121         }
3122         PyList_SET_ITEM(list, i, v);
3123     }
3124     return list;
3125 }
3126 
3127 void
PySys_SetArgvEx(int argc,wchar_t ** argv,int updatepath)3128 PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
3129 {
3130     wchar_t* empty_argv[1] = {L""};
3131 
3132     if (argc < 1 || argv == NULL) {
3133         /* Ensure at least one (empty) argument is seen */
3134         argv = empty_argv;
3135         argc = 1;
3136     }
3137 
3138     PyObject *av = make_sys_argv(argc, argv);
3139     if (av == NULL) {
3140         Py_FatalError("no mem for sys.argv");
3141     }
3142     if (PySys_SetObject("argv", av) != 0) {
3143         Py_DECREF(av);
3144         Py_FatalError("can't assign sys.argv");
3145     }
3146     Py_DECREF(av);
3147 
3148     if (updatepath) {
3149         /* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path.
3150            If argv[0] is a symlink, use the real path. */
3151         const PyWideStringList argv_list = {.length = argc, .items = argv};
3152         PyObject *path0 = NULL;
3153         if (_PyPathConfig_ComputeSysPath0(&argv_list, &path0)) {
3154             if (path0 == NULL) {
3155                 Py_FatalError("can't compute path0 from argv");
3156             }
3157 
3158             PyObject *sys_path = _PySys_GetObjectId(&PyId_path);
3159             if (sys_path != NULL) {
3160                 if (PyList_Insert(sys_path, 0, path0) < 0) {
3161                     Py_DECREF(path0);
3162                     Py_FatalError("can't prepend path0 to sys.path");
3163                 }
3164             }
3165             Py_DECREF(path0);
3166         }
3167     }
3168 }
3169 
3170 void
PySys_SetArgv(int argc,wchar_t ** argv)3171 PySys_SetArgv(int argc, wchar_t **argv)
3172 {
3173     PySys_SetArgvEx(argc, argv, Py_IsolatedFlag == 0);
3174 }
3175 
3176 /* Reimplementation of PyFile_WriteString() no calling indirectly
3177    PyErr_CheckSignals(): avoid the call to PyObject_Str(). */
3178 
3179 static int
sys_pyfile_write_unicode(PyObject * unicode,PyObject * file)3180 sys_pyfile_write_unicode(PyObject *unicode, PyObject *file)
3181 {
3182     PyObject *writer = NULL, *result = NULL;
3183     int err;
3184 
3185     if (file == NULL)
3186         return -1;
3187 
3188     writer = _PyObject_GetAttrId(file, &PyId_write);
3189     if (writer == NULL)
3190         goto error;
3191 
3192     result = PyObject_CallFunctionObjArgs(writer, unicode, NULL);
3193     if (result == NULL) {
3194         goto error;
3195     } else {
3196         err = 0;
3197         goto finally;
3198     }
3199 
3200 error:
3201     err = -1;
3202 finally:
3203     Py_XDECREF(writer);
3204     Py_XDECREF(result);
3205     return err;
3206 }
3207 
3208 static int
sys_pyfile_write(const char * text,PyObject * file)3209 sys_pyfile_write(const char *text, PyObject *file)
3210 {
3211     PyObject *unicode = NULL;
3212     int err;
3213 
3214     if (file == NULL)
3215         return -1;
3216 
3217     unicode = PyUnicode_FromString(text);
3218     if (unicode == NULL)
3219         return -1;
3220 
3221     err = sys_pyfile_write_unicode(unicode, file);
3222     Py_DECREF(unicode);
3223     return err;
3224 }
3225 
3226 /* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
3227    Adapted from code submitted by Just van Rossum.
3228 
3229    PySys_WriteStdout(format, ...)
3230    PySys_WriteStderr(format, ...)
3231 
3232       The first function writes to sys.stdout; the second to sys.stderr.  When
3233       there is a problem, they write to the real (C level) stdout or stderr;
3234       no exceptions are raised.
3235 
3236       PyErr_CheckSignals() is not called to avoid the execution of the Python
3237       signal handlers: they may raise a new exception whereas sys_write()
3238       ignores all exceptions.
3239 
3240       Both take a printf-style format string as their first argument followed
3241       by a variable length argument list determined by the format string.
3242 
3243       *** WARNING ***
3244 
3245       The format should limit the total size of the formatted output string to
3246       1000 bytes.  In particular, this means that no unrestricted "%s" formats
3247       should occur; these should be limited using "%.<N>s where <N> is a
3248       decimal number calculated so that <N> plus the maximum size of other
3249       formatted text does not exceed 1000 bytes.  Also watch out for "%f",
3250       which can print hundreds of digits for very large numbers.
3251 
3252  */
3253 
3254 static void
sys_write(_Py_Identifier * key,FILE * fp,const char * format,va_list va)3255 sys_write(_Py_Identifier *key, FILE *fp, const char *format, va_list va)
3256 {
3257     PyObject *file;
3258     PyObject *error_type, *error_value, *error_traceback;
3259     char buffer[1001];
3260     int written;
3261 
3262     PyErr_Fetch(&error_type, &error_value, &error_traceback);
3263     file = _PySys_GetObjectId(key);
3264     written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
3265     if (sys_pyfile_write(buffer, file) != 0) {
3266         PyErr_Clear();
3267         fputs(buffer, fp);
3268     }
3269     if (written < 0 || (size_t)written >= sizeof(buffer)) {
3270         const char *truncated = "... truncated";
3271         if (sys_pyfile_write(truncated, file) != 0)
3272             fputs(truncated, fp);
3273     }
3274     PyErr_Restore(error_type, error_value, error_traceback);
3275 }
3276 
3277 void
PySys_WriteStdout(const char * format,...)3278 PySys_WriteStdout(const char *format, ...)
3279 {
3280     va_list va;
3281 
3282     va_start(va, format);
3283     sys_write(&PyId_stdout, stdout, format, va);
3284     va_end(va);
3285 }
3286 
3287 void
PySys_WriteStderr(const char * format,...)3288 PySys_WriteStderr(const char *format, ...)
3289 {
3290     va_list va;
3291 
3292     va_start(va, format);
3293     sys_write(&PyId_stderr, stderr, format, va);
3294     va_end(va);
3295 }
3296 
3297 static void
sys_format(_Py_Identifier * key,FILE * fp,const char * format,va_list va)3298 sys_format(_Py_Identifier *key, FILE *fp, const char *format, va_list va)
3299 {
3300     PyObject *file, *message;
3301     PyObject *error_type, *error_value, *error_traceback;
3302     const char *utf8;
3303 
3304     PyErr_Fetch(&error_type, &error_value, &error_traceback);
3305     file = _PySys_GetObjectId(key);
3306     message = PyUnicode_FromFormatV(format, va);
3307     if (message != NULL) {
3308         if (sys_pyfile_write_unicode(message, file) != 0) {
3309             PyErr_Clear();
3310             utf8 = PyUnicode_AsUTF8(message);
3311             if (utf8 != NULL)
3312                 fputs(utf8, fp);
3313         }
3314         Py_DECREF(message);
3315     }
3316     PyErr_Restore(error_type, error_value, error_traceback);
3317 }
3318 
3319 void
PySys_FormatStdout(const char * format,...)3320 PySys_FormatStdout(const char *format, ...)
3321 {
3322     va_list va;
3323 
3324     va_start(va, format);
3325     sys_format(&PyId_stdout, stdout, format, va);
3326     va_end(va);
3327 }
3328 
3329 void
PySys_FormatStderr(const char * format,...)3330 PySys_FormatStderr(const char *format, ...)
3331 {
3332     va_list va;
3333 
3334     va_start(va, format);
3335     sys_format(&PyId_stderr, stderr, format, va);
3336     va_end(va);
3337 }
3338