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