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