LCOV - code coverage report
Current view: top level - Python - sysmodule.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 821 1169 70.2 %
Date: 2022-07-07 18:19:46 Functions: 85 99 85.9 %

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

Generated by: LCOV version 1.14