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