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