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