LCOV - code coverage report
Current view: top level - Python - pythonrun.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 750 1025 73.2 %
Date: 2022-07-07 18:19:46 Functions: 39 59 66.1 %

          Line data    Source code
       1             : 
       2             : /* Top level execution of Python code (including in __main__) */
       3             : 
       4             : /* To help control the interfaces between the startup, execution and
       5             :  * shutdown code, the phases are split across separate modules (bootstrap,
       6             :  * pythonrun, shutdown)
       7             :  */
       8             : 
       9             : /* TODO: Cull includes following phase split */
      10             : 
      11             : #include <stdbool.h>
      12             : 
      13             : #include "Python.h"
      14             : 
      15             : #include "pycore_ast.h"           // PyAST_mod2obj
      16             : #include "pycore_ceval.h"         // _Py_EnterRecursiveCall
      17             : #include "pycore_compile.h"       // _PyAST_Compile()
      18             : #include "pycore_interp.h"        // PyInterpreterState.importlib
      19             : #include "pycore_object.h"        // _PyDebug_PrintTotalRefs()
      20             : #include "pycore_parser.h"        // _PyParser_ASTFromString()
      21             : #include "pycore_pyerrors.h"      // _PyErr_Fetch, _Py_Offer_Suggestions
      22             : #include "pycore_pylifecycle.h"   // _Py_UnhandledKeyboardInterrupt
      23             : #include "pycore_pystate.h"       // _PyInterpreterState_GET()
      24             : #include "pycore_sysmodule.h"     // _PySys_Audit()
      25             : #include "pycore_traceback.h"     // _PyTraceBack_Print_Indented()
      26             : 
      27             : #include "errcode.h"              // E_EOF
      28             : #include "marshal.h"              // PyMarshal_ReadLongFromFile()
      29             : 
      30             : #ifdef MS_WINDOWS
      31             : #  include "malloc.h"             // alloca()
      32             : #endif
      33             : 
      34             : #ifdef MS_WINDOWS
      35             : #  undef BYTE
      36             : #  include "windows.h"
      37             : #endif
      38             : 
      39             : 
      40             : #ifdef __cplusplus
      41             : extern "C" {
      42             : #endif
      43             : 
      44             : /* Forward */
      45             : static void flush_io(void);
      46             : static PyObject *run_mod(mod_ty, PyObject *, PyObject *, PyObject *,
      47             :                           PyCompilerFlags *, PyArena *);
      48             : static PyObject *run_pyc_file(FILE *, PyObject *, PyObject *,
      49             :                               PyCompilerFlags *);
      50             : static int PyRun_InteractiveOneObjectEx(FILE *, PyObject *, PyCompilerFlags *);
      51             : static PyObject* pyrun_file(FILE *fp, PyObject *filename, int start,
      52             :                             PyObject *globals, PyObject *locals, int closeit,
      53             :                             PyCompilerFlags *flags);
      54             : 
      55             : 
      56             : int
      57         363 : _PyRun_AnyFileObject(FILE *fp, PyObject *filename, int closeit,
      58             :                      PyCompilerFlags *flags)
      59             : {
      60         363 :     int decref_filename = 0;
      61         363 :     if (filename == NULL) {
      62           0 :         filename = PyUnicode_FromString("???");
      63           0 :         if (filename == NULL) {
      64           0 :             PyErr_Print();
      65           0 :             return -1;
      66             :         }
      67           0 :         decref_filename = 1;
      68             :     }
      69             : 
      70             :     int res;
      71         363 :     if (_Py_FdIsInteractive(fp, filename)) {
      72          12 :         res = _PyRun_InteractiveLoopObject(fp, filename, flags);
      73           8 :         if (closeit) {
      74           0 :             fclose(fp);
      75             :         }
      76             :     }
      77             :     else {
      78         351 :         res = _PyRun_SimpleFileObject(fp, filename, closeit, flags);
      79             :     }
      80             : 
      81         312 :     if (decref_filename) {
      82           0 :         Py_DECREF(filename);
      83             :     }
      84         312 :     return res;
      85             : }
      86             : 
      87             : 
      88             : /* Parse input from a file and execute it */
      89             : int
      90          25 : PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit,
      91             :                      PyCompilerFlags *flags)
      92             : {
      93             :     PyObject *filename_obj;
      94          25 :     if (filename != NULL) {
      95          25 :         filename_obj = PyUnicode_DecodeFSDefault(filename);
      96          25 :         if (filename_obj == NULL) {
      97           0 :             PyErr_Print();
      98           0 :             return -1;
      99             :         }
     100             :     }
     101             :     else {
     102           0 :         filename_obj = NULL;
     103             :     }
     104          25 :     int res = _PyRun_AnyFileObject(fp, filename_obj, closeit, flags);
     105          21 :     Py_XDECREF(filename_obj);
     106          21 :     return res;
     107             : }
     108             : 
     109             : 
     110             : int
     111          12 : _PyRun_InteractiveLoopObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
     112             : {
     113          12 :     PyCompilerFlags local_flags = _PyCompilerFlags_INIT;
     114          12 :     if (flags == NULL) {
     115           0 :         flags = &local_flags;
     116             :     }
     117             : 
     118          12 :     PyThreadState *tstate = _PyThreadState_GET();
     119          12 :     PyObject *v = _PySys_GetAttr(tstate, &_Py_ID(ps1));
     120          12 :     if (v == NULL) {
     121          12 :         _PySys_SetAttr(&_Py_ID(ps1), v = PyUnicode_FromString(">>> "));
     122          12 :         Py_XDECREF(v);
     123             :     }
     124          12 :     v = _PySys_GetAttr(tstate, &_Py_ID(ps2));
     125          12 :     if (v == NULL) {
     126          12 :         _PySys_SetAttr(&_Py_ID(ps2), v = PyUnicode_FromString("... "));
     127          12 :         Py_XDECREF(v);
     128             :     }
     129             : 
     130             : #ifdef Py_REF_DEBUG
     131          12 :     int show_ref_count = _Py_GetConfig()->show_ref_count;
     132             : #endif
     133          12 :     int err = 0;
     134             :     int ret;
     135          12 :     int nomem_count = 0;
     136             :     do {
     137          47 :         ret = PyRun_InteractiveOneObjectEx(fp, filename, flags);
     138          47 :         if (ret == -1 && PyErr_Occurred()) {
     139             :             /* Prevent an endless loop after multiple consecutive MemoryErrors
     140             :              * while still allowing an interactive command to fail with a
     141             :              * MemoryError. */
     142          25 :             if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
     143          17 :                 if (++nomem_count > 16) {
     144           1 :                     PyErr_Clear();
     145           1 :                     err = -1;
     146           1 :                     break;
     147             :                 }
     148             :             } else {
     149           8 :                 nomem_count = 0;
     150             :             }
     151          24 :             PyErr_Print();
     152          20 :             flush_io();
     153             :         } else {
     154          22 :             nomem_count = 0;
     155             :         }
     156             : #ifdef Py_REF_DEBUG
     157          42 :         if (show_ref_count) {
     158           0 :             _PyDebug_PrintTotalRefs();
     159             :         }
     160             : #endif
     161          42 :     } while (ret != E_EOF);
     162           8 :     return err;
     163             : }
     164             : 
     165             : 
     166             : int
     167           0 : PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
     168             : {
     169           0 :     PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename);
     170           0 :     if (filename_obj == NULL) {
     171           0 :         PyErr_Print();
     172           0 :         return -1;
     173             :     }
     174             : 
     175           0 :     int err = _PyRun_InteractiveLoopObject(fp, filename_obj, flags);
     176           0 :     Py_DECREF(filename_obj);
     177           0 :     return err;
     178             : 
     179             : }
     180             : 
     181             : 
     182             : /* A PyRun_InteractiveOneObject() auxiliary function that does not print the
     183             :  * error on failure. */
     184             : static int
     185          47 : PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename,
     186             :                              PyCompilerFlags *flags)
     187             : {
     188          47 :     PyObject *m, *d, *v, *w, *oenc = NULL;
     189             :     mod_ty mod;
     190             :     PyArena *arena;
     191          47 :     const char *ps1 = "", *ps2 = "", *enc = NULL;
     192          47 :     int errcode = 0;
     193          47 :     PyThreadState *tstate = _PyThreadState_GET();
     194             : 
     195          47 :     if (fp == stdin) {
     196             :         /* Fetch encoding from sys.stdin if possible. */
     197          47 :         v = _PySys_GetAttr(tstate, &_Py_ID(stdin));
     198          47 :         if (v && v != Py_None) {
     199          47 :             oenc = PyObject_GetAttr(v, &_Py_ID(encoding));
     200          47 :             if (oenc)
     201          47 :                 enc = PyUnicode_AsUTF8(oenc);
     202          47 :             if (!enc)
     203           0 :                 PyErr_Clear();
     204             :         }
     205             :     }
     206          47 :     v = _PySys_GetAttr(tstate, &_Py_ID(ps1));
     207          47 :     if (v != NULL) {
     208          47 :         v = PyObject_Str(v);
     209          47 :         if (v == NULL)
     210           0 :             PyErr_Clear();
     211          47 :         else if (PyUnicode_Check(v)) {
     212          47 :             ps1 = PyUnicode_AsUTF8(v);
     213          47 :             if (ps1 == NULL) {
     214           0 :                 PyErr_Clear();
     215           0 :                 ps1 = "";
     216             :             }
     217             :         }
     218             :     }
     219          47 :     w = _PySys_GetAttr(tstate, &_Py_ID(ps2));
     220          47 :     if (w != NULL) {
     221          47 :         w = PyObject_Str(w);
     222          47 :         if (w == NULL)
     223           0 :             PyErr_Clear();
     224          47 :         else if (PyUnicode_Check(w)) {
     225          47 :             ps2 = PyUnicode_AsUTF8(w);
     226          47 :             if (ps2 == NULL) {
     227           0 :                 PyErr_Clear();
     228           0 :                 ps2 = "";
     229             :             }
     230             :         }
     231             :     }
     232          47 :     arena = _PyArena_New();
     233          47 :     if (arena == NULL) {
     234          17 :         Py_XDECREF(v);
     235          17 :         Py_XDECREF(w);
     236          17 :         Py_XDECREF(oenc);
     237          17 :         return -1;
     238             :     }
     239             : 
     240          30 :     mod = _PyParser_ASTFromFile(fp, filename, enc, Py_single_input,
     241             :                                 ps1, ps2, flags, &errcode, arena);
     242             : 
     243          30 :     Py_XDECREF(v);
     244          30 :     Py_XDECREF(w);
     245          30 :     Py_XDECREF(oenc);
     246          30 :     if (mod == NULL) {
     247           8 :         _PyArena_Free(arena);
     248           8 :         if (errcode == E_EOF) {
     249           7 :             PyErr_Clear();
     250           7 :             return E_EOF;
     251             :         }
     252           1 :         return -1;
     253             :     }
     254          22 :     m = PyImport_AddModuleObject(&_Py_ID(__main__));
     255          22 :     if (m == NULL) {
     256           0 :         _PyArena_Free(arena);
     257           0 :         return -1;
     258             :     }
     259          22 :     d = PyModule_GetDict(m);
     260          22 :     v = run_mod(mod, filename, d, d, flags, arena);
     261          22 :     _PyArena_Free(arena);
     262          22 :     if (v == NULL) {
     263           7 :         return -1;
     264             :     }
     265          15 :     Py_DECREF(v);
     266          15 :     flush_io();
     267          15 :     return 0;
     268             : }
     269             : 
     270             : int
     271           0 : PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
     272             : {
     273             :     int res;
     274             : 
     275           0 :     res = PyRun_InteractiveOneObjectEx(fp, filename, flags);
     276           0 :     if (res == -1) {
     277           0 :         PyErr_Print();
     278           0 :         flush_io();
     279             :     }
     280           0 :     return res;
     281             : }
     282             : 
     283             : int
     284           0 : PyRun_InteractiveOneFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags)
     285             : {
     286             :     PyObject *filename;
     287             :     int res;
     288             : 
     289           0 :     filename = PyUnicode_DecodeFSDefault(filename_str);
     290           0 :     if (filename == NULL) {
     291           0 :         PyErr_Print();
     292           0 :         return -1;
     293             :     }
     294           0 :     res = PyRun_InteractiveOneObject(fp, filename, flags);
     295           0 :     Py_DECREF(filename);
     296           0 :     return res;
     297             : }
     298             : 
     299             : 
     300             : /* Check whether a file maybe a pyc file: Look at the extension,
     301             :    the file type, and, if we may close it, at the first few bytes. */
     302             : 
     303             : static int
     304         352 : maybe_pyc_file(FILE *fp, PyObject *filename, int closeit)
     305             : {
     306         352 :     PyObject *ext = PyUnicode_FromString(".pyc");
     307         352 :     if (ext == NULL) {
     308           0 :         return -1;
     309             :     }
     310         352 :     Py_ssize_t endswith = PyUnicode_Tailmatch(filename, ext, 0, PY_SSIZE_T_MAX, +1);
     311         352 :     Py_DECREF(ext);
     312         352 :     if (endswith) {
     313          28 :         return 1;
     314             :     }
     315             : 
     316             :     /* Only look into the file if we are allowed to close it, since
     317             :        it then should also be seekable. */
     318         324 :     if (!closeit) {
     319          14 :         return 0;
     320             :     }
     321             : 
     322             :     /* Read only two bytes of the magic. If the file was opened in
     323             :        text mode, the bytes 3 and 4 of the magic (\r\n) might not
     324             :        be read as they are on disk. */
     325         310 :     unsigned int halfmagic = PyImport_GetMagicNumber() & 0xFFFF;
     326             :     unsigned char buf[2];
     327             :     /* Mess:  In case of -x, the stream is NOT at its start now,
     328             :        and ungetc() was used to push back the first newline,
     329             :        which makes the current stream position formally undefined,
     330             :        and a x-platform nightmare.
     331             :        Unfortunately, we have no direct way to know whether -x
     332             :        was specified.  So we use a terrible hack:  if the current
     333             :        stream position is not 0, we assume -x was specified, and
     334             :        give up.  Bug 132850 on SourceForge spells out the
     335             :        hopelessness of trying anything else (fseek and ftell
     336             :        don't work predictably x-platform for text-mode files).
     337             :     */
     338         310 :     int ispyc = 0;
     339         310 :     if (ftell(fp) == 0) {
     340         310 :         if (fread(buf, 1, 2, fp) == 2 &&
     341         308 :             ((unsigned int)buf[1]<<8 | buf[0]) == halfmagic)
     342           0 :             ispyc = 1;
     343         310 :         rewind(fp);
     344             :     }
     345         310 :     return ispyc;
     346             : }
     347             : 
     348             : 
     349             : static int
     350         339 : set_main_loader(PyObject *d, PyObject *filename, const char *loader_name)
     351             : {
     352         339 :     PyInterpreterState *interp = _PyInterpreterState_GET();
     353         339 :     PyObject *bootstrap = PyObject_GetAttrString(interp->importlib,
     354             :                                                  "_bootstrap_external");
     355         339 :     if (bootstrap == NULL) {
     356           0 :         return -1;
     357             :     }
     358             : 
     359         339 :     PyObject *loader_type = PyObject_GetAttrString(bootstrap, loader_name);
     360         339 :     Py_DECREF(bootstrap);
     361         339 :     if (loader_type == NULL) {
     362           0 :         return -1;
     363             :     }
     364             : 
     365         339 :     PyObject *loader = PyObject_CallFunction(loader_type,
     366             :                                              "sO", "__main__", filename);
     367         339 :     Py_DECREF(loader_type);
     368         339 :     if (loader == NULL) {
     369           0 :         return -1;
     370             :     }
     371             : 
     372         339 :     if (PyDict_SetItemString(d, "__loader__", loader) < 0) {
     373           0 :         Py_DECREF(loader);
     374           0 :         return -1;
     375             :     }
     376         339 :     Py_DECREF(loader);
     377         339 :     return 0;
     378             : }
     379             : 
     380             : 
     381             : int
     382         352 : _PyRun_SimpleFileObject(FILE *fp, PyObject *filename, int closeit,
     383             :                         PyCompilerFlags *flags)
     384             : {
     385             :     PyObject *m, *d, *v;
     386         352 :     int set_file_name = 0, ret = -1;
     387             : 
     388         352 :     m = PyImport_AddModule("__main__");
     389         352 :     if (m == NULL)
     390           0 :         return -1;
     391         352 :     Py_INCREF(m);
     392         352 :     d = PyModule_GetDict(m);
     393         352 :     if (_PyDict_GetItemStringWithError(d, "__file__") == NULL) {
     394         352 :         if (PyErr_Occurred()) {
     395           0 :             goto done;
     396             :         }
     397         352 :         if (PyDict_SetItemString(d, "__file__", filename) < 0) {
     398           0 :             goto done;
     399             :         }
     400         352 :         if (PyDict_SetItemString(d, "__cached__", Py_None) < 0) {
     401           0 :             goto done;
     402             :         }
     403         352 :         set_file_name = 1;
     404             :     }
     405             : 
     406         352 :     int pyc = maybe_pyc_file(fp, filename, closeit);
     407         352 :     if (pyc < 0) {
     408           0 :         goto done;
     409             :     }
     410             : 
     411         352 :     if (pyc) {
     412             :         FILE *pyc_fp;
     413             :         /* Try to run a pyc file. First, re-open in binary */
     414          28 :         if (closeit) {
     415          28 :             fclose(fp);
     416             :         }
     417             : 
     418          28 :         pyc_fp = _Py_fopen_obj(filename, "rb");
     419          28 :         if (pyc_fp == NULL) {
     420           0 :             fprintf(stderr, "python: Can't reopen .pyc file\n");
     421           0 :             goto done;
     422             :         }
     423             : 
     424          28 :         if (set_main_loader(d, filename, "SourcelessFileLoader") < 0) {
     425           0 :             fprintf(stderr, "python: failed to set __main__.__loader__\n");
     426           0 :             ret = -1;
     427           0 :             fclose(pyc_fp);
     428           0 :             goto done;
     429             :         }
     430          28 :         v = run_pyc_file(pyc_fp, d, d, flags);
     431             :     } else {
     432             :         /* When running from stdin, leave __main__.__loader__ alone */
     433         635 :         if (PyUnicode_CompareWithASCIIString(filename, "<stdin>") != 0 &&
     434         311 :             set_main_loader(d, filename, "SourceFileLoader") < 0) {
     435           0 :             fprintf(stderr, "python: failed to set __main__.__loader__\n");
     436           0 :             ret = -1;
     437           0 :             goto done;
     438             :         }
     439         324 :         v = pyrun_file(fp, filename, Py_file_input, d, d,
     440             :                        closeit, flags);
     441             :     }
     442         352 :     flush_io();
     443         352 :     if (v == NULL) {
     444         109 :         Py_CLEAR(m);
     445         109 :         PyErr_Print();
     446          62 :         goto done;
     447             :     }
     448         243 :     Py_DECREF(v);
     449         243 :     ret = 0;
     450         305 :   done:
     451         305 :     if (set_file_name) {
     452         305 :         if (PyDict_DelItemString(d, "__file__")) {
     453           0 :             PyErr_Clear();
     454             :         }
     455         305 :         if (PyDict_DelItemString(d, "__cached__")) {
     456           0 :             PyErr_Clear();
     457             :         }
     458             :     }
     459         305 :     Py_XDECREF(m);
     460         305 :     return ret;
     461             : }
     462             : 
     463             : 
     464             : int
     465           0 : PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
     466             :                         PyCompilerFlags *flags)
     467             : {
     468           0 :     PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename);
     469           0 :     if (filename_obj == NULL) {
     470           0 :         return -1;
     471             :     }
     472           0 :     int res = _PyRun_SimpleFileObject(fp, filename_obj, closeit, flags);
     473           0 :     Py_DECREF(filename_obj);
     474           0 :     return res;
     475             : }
     476             : 
     477             : 
     478             : int
     479        1735 : PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
     480             : {
     481             :     PyObject *m, *d, *v;
     482        1735 :     m = PyImport_AddModule("__main__");
     483        1735 :     if (m == NULL)
     484           0 :         return -1;
     485        1735 :     d = PyModule_GetDict(m);
     486        1735 :     v = PyRun_StringFlags(command, Py_file_input, d, d, flags);
     487        1733 :     if (v == NULL) {
     488         768 :         PyErr_Print();
     489          96 :         return -1;
     490             :     }
     491         965 :     Py_DECREF(v);
     492         965 :     return 0;
     493             : }
     494             : 
     495             : static int
     496          66 : parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename,
     497             :                    Py_ssize_t *lineno, Py_ssize_t *offset,
     498             :                    Py_ssize_t* end_lineno, Py_ssize_t* end_offset,
     499             :                    PyObject **text)
     500             : {
     501             :     Py_ssize_t hold;
     502             :     PyObject *v;
     503             : 
     504          66 :     *message = NULL;
     505          66 :     *filename = NULL;
     506             : 
     507             :     /* new style errors.  `err' is an instance */
     508          66 :     *message = PyObject_GetAttr(err, &_Py_ID(msg));
     509          66 :     if (!*message)
     510           0 :         goto finally;
     511             : 
     512          66 :     v = PyObject_GetAttr(err, &_Py_ID(filename));
     513          66 :     if (!v)
     514           0 :         goto finally;
     515          66 :     if (v == Py_None) {
     516           5 :         Py_DECREF(v);
     517             :         _Py_DECLARE_STR(anon_string, "<string>");
     518           5 :         *filename = &_Py_STR(anon_string);
     519           5 :         Py_INCREF(*filename);
     520             :     }
     521             :     else {
     522          61 :         *filename = v;
     523             :     }
     524             : 
     525          66 :     v = PyObject_GetAttr(err, &_Py_ID(lineno));
     526          66 :     if (!v)
     527           0 :         goto finally;
     528          66 :     hold = PyLong_AsSsize_t(v);
     529          66 :     Py_DECREF(v);
     530          66 :     if (hold < 0 && PyErr_Occurred())
     531           5 :         goto finally;
     532          61 :     *lineno = hold;
     533             : 
     534          61 :     v = PyObject_GetAttr(err, &_Py_ID(offset));
     535          61 :     if (!v)
     536           0 :         goto finally;
     537          61 :     if (v == Py_None) {
     538           2 :         *offset = -1;
     539           2 :         Py_DECREF(v);
     540             :     } else {
     541          59 :         hold = PyLong_AsSsize_t(v);
     542          59 :         Py_DECREF(v);
     543          59 :         if (hold < 0 && PyErr_Occurred())
     544           0 :             goto finally;
     545          59 :         *offset = hold;
     546             :     }
     547             : 
     548          61 :     if (Py_TYPE(err) == (PyTypeObject*)PyExc_SyntaxError) {
     549          61 :         v = PyObject_GetAttr(err, &_Py_ID(end_lineno));
     550          61 :         if (!v) {
     551           0 :             PyErr_Clear();
     552           0 :             *end_lineno = *lineno;
     553             :         }
     554          61 :         else if (v == Py_None) {
     555          34 :             *end_lineno = *lineno;
     556          34 :             Py_DECREF(v);
     557             :         } else {
     558          27 :             hold = PyLong_AsSsize_t(v);
     559          27 :             Py_DECREF(v);
     560          27 :             if (hold < 0 && PyErr_Occurred())
     561           0 :                 goto finally;
     562          27 :             *end_lineno = hold;
     563             :         }
     564             : 
     565          61 :         v = PyObject_GetAttr(err, &_Py_ID(end_offset));
     566          61 :         if (!v) {
     567           0 :             PyErr_Clear();
     568           0 :             *end_offset = -1;
     569             :         }
     570          61 :         else if (v == Py_None) {
     571          34 :             *end_offset = -1;
     572          34 :             Py_DECREF(v);
     573             :         } else {
     574          27 :             hold = PyLong_AsSsize_t(v);
     575          27 :             Py_DECREF(v);
     576          27 :             if (hold < 0 && PyErr_Occurred())
     577           0 :                 goto finally;
     578          27 :             *end_offset = hold;
     579             :         }
     580             :     } else {
     581             :         // SyntaxError subclasses
     582           0 :         *end_lineno = *lineno;
     583           0 :         *end_offset = -1;
     584             :     }
     585             : 
     586          61 :     v = PyObject_GetAttr(err, &_Py_ID(text));
     587          61 :     if (!v)
     588           0 :         goto finally;
     589          61 :     if (v == Py_None) {
     590           2 :         Py_DECREF(v);
     591           2 :         *text = NULL;
     592             :     }
     593             :     else {
     594          59 :         *text = v;
     595             :     }
     596          61 :     return 1;
     597             : 
     598           5 : finally:
     599           5 :     Py_XDECREF(*message);
     600           5 :     Py_XDECREF(*filename);
     601           5 :     return 0;
     602             : }
     603             : 
     604             : static int
     605          59 : print_error_text(PyObject *f, Py_ssize_t offset, Py_ssize_t end_offset,
     606             :                  PyObject *text_obj)
     607             : {
     608          18 :     size_t caret_repetitions = (end_offset > 0 && end_offset > offset) ?
     609          77 :                                end_offset - offset : 1;
     610             : 
     611             :     /* Convert text to a char pointer; return if error */
     612          59 :     const char *text = PyUnicode_AsUTF8(text_obj);
     613          59 :     if (text == NULL) {
     614           0 :         return -1;
     615             :     }
     616             : 
     617             :     /* Convert offset from 1-based to 0-based */
     618          59 :     offset--;
     619             : 
     620             :     /* Strip leading whitespace from text, adjusting offset as we go */
     621         102 :     while (*text == ' ' || *text == '\t' || *text == '\f') {
     622          43 :         text++;
     623          43 :         offset--;
     624             :     }
     625             : 
     626             :     /* Calculate text length excluding trailing newline */
     627          59 :     Py_ssize_t len = strlen(text);
     628          59 :     if (len > 0 && text[len-1] == '\n') {
     629           9 :         len--;
     630             :     }
     631             : 
     632             :     /* Clip offset to at most len */
     633          59 :     if (offset > len) {
     634           6 :         offset = len;
     635             :     }
     636             : 
     637             :     /* Skip past newlines embedded in text */
     638           0 :     for (;;) {
     639          59 :         const char *nl = strchr(text, '\n');
     640          59 :         if (nl == NULL) {
     641          50 :             break;
     642             :         }
     643           9 :         Py_ssize_t inl = nl - text;
     644           9 :         if (inl >= offset) {
     645           9 :             break;
     646             :         }
     647           0 :         inl += 1;
     648           0 :         text += inl;
     649           0 :         len -= inl;
     650           0 :         offset -= (int)inl;
     651             :     }
     652             : 
     653             :     /* Print text */
     654          59 :     if (PyFile_WriteString("    ", f) < 0) {
     655           0 :         return -1;
     656             :     }
     657          59 :     if (PyFile_WriteString(text, f) < 0) {
     658           0 :         return -1;
     659             :     }
     660             : 
     661             :     /* Make sure there's a newline at the end */
     662          59 :     if (text[len] != '\n') {
     663          50 :         if (PyFile_WriteString("\n", f) < 0) {
     664           0 :             return -1;
     665             :         }
     666             :     }
     667             : 
     668             :     /* Don't print caret if it points to the left of the text */
     669          59 :     if (offset < 0) {
     670          18 :         return 0;
     671             :     }
     672             : 
     673             :     /* Write caret line */
     674          41 :     if (PyFile_WriteString("    ", f) < 0) {
     675           0 :         return -1;
     676             :     }
     677         200 :     while (--offset >= 0) {
     678         159 :         if (PyFile_WriteString(" ", f) < 0) {
     679           0 :             return -1;
     680             :         }
     681             :     }
     682         134 :     for (size_t caret_iter=0; caret_iter < caret_repetitions ; caret_iter++) {
     683          93 :         if (PyFile_WriteString("^", f) < 0) {
     684           0 :             return -1;
     685             :         }
     686             :     }
     687          41 :     if (PyFile_WriteString("\n", f) < 0) {
     688           0 :         return -1;
     689             :     }
     690          41 :     return 0;
     691             : }
     692             : 
     693             : 
     694             : int
     695        1663 : _Py_HandleSystemExit(int *exitcode_p)
     696             : {
     697        1663 :     int inspect = _Py_GetConfig()->inspect;
     698        1663 :     if (inspect) {
     699             :         /* Don't exit if -i flag was given. This flag is set to 0
     700             :          * when entering interactive mode for inspecting. */
     701           2 :         return 0;
     702             :     }
     703             : 
     704        1661 :     if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
     705         224 :         return 0;
     706             :     }
     707             : 
     708             :     PyObject *exception, *value, *tb;
     709        1437 :     PyErr_Fetch(&exception, &value, &tb);
     710             : 
     711        1437 :     fflush(stdout);
     712             : 
     713        1437 :     int exitcode = 0;
     714        1437 :     if (value == NULL || value == Py_None) {
     715           2 :         goto done;
     716             :     }
     717             : 
     718        1435 :     if (PyExceptionInstance_Check(value)) {
     719             :         /* The error code should be in the `code' attribute. */
     720         638 :         PyObject *code = PyObject_GetAttr(value, &_Py_ID(code));
     721         638 :         if (code) {
     722         637 :             Py_DECREF(value);
     723         637 :             value = code;
     724         637 :             if (value == Py_None)
     725          41 :                 goto done;
     726             :         }
     727             :         /* If we failed to dig out the 'code' attribute,
     728             :            just let the else clause below print the error. */
     729             :     }
     730             : 
     731        1394 :     if (PyLong_Check(value)) {
     732        1373 :         exitcode = (int)PyLong_AsLong(value);
     733             :     }
     734             :     else {
     735          21 :         PyThreadState *tstate = _PyThreadState_GET();
     736          21 :         PyObject *sys_stderr = _PySys_GetAttr(tstate, &_Py_ID(stderr));
     737             :         /* We clear the exception here to avoid triggering the assertion
     738             :          * in PyObject_Str that ensures it won't silently lose exception
     739             :          * details.
     740             :          */
     741          21 :         PyErr_Clear();
     742          21 :         if (sys_stderr != NULL && sys_stderr != Py_None) {
     743          21 :             PyFile_WriteObject(value, sys_stderr, Py_PRINT_RAW);
     744             :         } else {
     745           0 :             PyObject_Print(value, stderr, Py_PRINT_RAW);
     746           0 :             fflush(stderr);
     747             :         }
     748          21 :         PySys_WriteStderr("\n");
     749          21 :         exitcode = 1;
     750             :     }
     751             : 
     752        1437 :  done:
     753             :     /* Restore and clear the exception info, in order to properly decref
     754             :      * the exception, value, and traceback.      If we just exit instead,
     755             :      * these leak, which confuses PYTHONDUMPREFS output, and may prevent
     756             :      * some finalizers from running.
     757             :      */
     758        1437 :     PyErr_Restore(exception, value, tb);
     759        1437 :     PyErr_Clear();
     760        1437 :     *exitcode_p = exitcode;
     761        1437 :     return 1;
     762             : }
     763             : 
     764             : 
     765             : static void
     766         925 : handle_system_exit(void)
     767             : {
     768             :     int exitcode;
     769         925 :     if (_Py_HandleSystemExit(&exitcode)) {
     770         723 :         Py_Exit(exitcode);
     771             :     }
     772         202 : }
     773             : 
     774             : 
     775             : static void
     776         925 : _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
     777             : {
     778             :     PyObject *exception, *v, *tb, *hook;
     779             : 
     780         925 :     handle_system_exit();
     781             : 
     782         202 :     _PyErr_Fetch(tstate, &exception, &v, &tb);
     783         202 :     if (exception == NULL) {
     784           0 :         goto done;
     785             :     }
     786             : 
     787         202 :     _PyErr_NormalizeException(tstate, &exception, &v, &tb);
     788         202 :     if (tb == NULL) {
     789          57 :         tb = Py_None;
     790          57 :         Py_INCREF(tb);
     791             :     }
     792         202 :     PyException_SetTraceback(v, tb);
     793         202 :     if (exception == NULL) {
     794           0 :         goto done;
     795             :     }
     796             : 
     797             :     /* Now we know v != NULL too */
     798         202 :     if (set_sys_last_vars) {
     799         202 :         if (_PySys_SetAttr(&_Py_ID(last_type), exception) < 0) {
     800           0 :             _PyErr_Clear(tstate);
     801             :         }
     802         202 :         if (_PySys_SetAttr(&_Py_ID(last_value), v) < 0) {
     803           0 :             _PyErr_Clear(tstate);
     804             :         }
     805         202 :         if (_PySys_SetAttr(&_Py_ID(last_traceback), tb) < 0) {
     806           0 :             _PyErr_Clear(tstate);
     807             :         }
     808             :     }
     809         202 :     hook = _PySys_GetAttr(tstate, &_Py_ID(excepthook));
     810         202 :     if (_PySys_Audit(tstate, "sys.excepthook", "OOOO", hook ? hook : Py_None,
     811             :                      exception, v, tb) < 0) {
     812           0 :         if (PyErr_ExceptionMatches(PyExc_RuntimeError)) {
     813           0 :             PyErr_Clear();
     814           0 :             goto done;
     815             :         }
     816           0 :         _PyErr_WriteUnraisableMsg("in audit hook", NULL);
     817             :     }
     818         202 :     if (hook) {
     819             :         PyObject* stack[3];
     820             :         PyObject *result;
     821             : 
     822         202 :         stack[0] = exception;
     823         202 :         stack[1] = v;
     824         202 :         stack[2] = tb;
     825         202 :         result = _PyObject_FastCall(hook, stack, 3);
     826         202 :         if (result == NULL) {
     827           0 :             handle_system_exit();
     828             : 
     829             :             PyObject *exception2, *v2, *tb2;
     830           0 :             _PyErr_Fetch(tstate, &exception2, &v2, &tb2);
     831           0 :             _PyErr_NormalizeException(tstate, &exception2, &v2, &tb2);
     832             :             /* It should not be possible for exception2 or v2
     833             :                to be NULL. However PyErr_Display() can't
     834             :                tolerate NULLs, so just be safe. */
     835           0 :             if (exception2 == NULL) {
     836           0 :                 exception2 = Py_None;
     837           0 :                 Py_INCREF(exception2);
     838             :             }
     839           0 :             if (v2 == NULL) {
     840           0 :                 v2 = Py_None;
     841           0 :                 Py_INCREF(v2);
     842             :             }
     843           0 :             fflush(stdout);
     844           0 :             PySys_WriteStderr("Error in sys.excepthook:\n");
     845           0 :             PyErr_Display(exception2, v2, tb2);
     846           0 :             PySys_WriteStderr("\nOriginal exception was:\n");
     847           0 :             PyErr_Display(exception, v, tb);
     848           0 :             Py_DECREF(exception2);
     849           0 :             Py_DECREF(v2);
     850           0 :             Py_XDECREF(tb2);
     851             :         }
     852         202 :         Py_XDECREF(result);
     853             :     }
     854             :     else {
     855           0 :         PySys_WriteStderr("sys.excepthook is missing\n");
     856           0 :         PyErr_Display(exception, v, tb);
     857             :     }
     858             : 
     859         202 : done:
     860         202 :     Py_XDECREF(exception);
     861         202 :     Py_XDECREF(v);
     862         202 :     Py_XDECREF(tb);
     863         202 : }
     864             : 
     865             : void
     866           0 : _PyErr_Print(PyThreadState *tstate)
     867             : {
     868           0 :     _PyErr_PrintEx(tstate, 1);
     869           0 : }
     870             : 
     871             : void
     872         925 : PyErr_PrintEx(int set_sys_last_vars)
     873             : {
     874         925 :     PyThreadState *tstate = _PyThreadState_GET();
     875         925 :     _PyErr_PrintEx(tstate, set_sys_last_vars);
     876         202 : }
     877             : 
     878             : void
     879         925 : PyErr_Print(void)
     880             : {
     881         925 :     PyErr_PrintEx(1);
     882         202 : }
     883             : 
     884             : struct exception_print_context
     885             : {
     886             :     PyObject *file;
     887             :     PyObject *seen;            // Prevent cycles in recursion
     888             :     int exception_group_depth; // nesting level of current exception group
     889             :     bool need_close;           // Need a closing bottom frame
     890             :     int max_group_width;       // Maximum number of children of each EG
     891             :     int max_group_depth;       // Maximum nesting level of EGs
     892             : };
     893             : 
     894             : #define EXC_MARGIN(ctx) ((ctx)->exception_group_depth ? "| " : "")
     895             : #define EXC_INDENT(ctx) (2 * (ctx)->exception_group_depth)
     896             : 
     897             : static int
     898         635 : write_indented_margin(struct exception_print_context *ctx, PyObject *f)
     899             : {
     900         635 :     return _Py_WriteIndentedMargin(EXC_INDENT(ctx), EXC_MARGIN(ctx), f);
     901             : }
     902             : 
     903             : static int
     904           2 : print_exception_invalid_type(struct exception_print_context *ctx,
     905             :                              PyObject *value)
     906             : {
     907           2 :     PyObject *f = ctx->file;
     908           2 :     if (_Py_WriteIndent(EXC_INDENT(ctx), f) < 0) {
     909           0 :         return -1;
     910             :     }
     911           2 :     const char *const msg = "TypeError: print_exception(): Exception expected "
     912             :                             "for value, ";
     913           2 :     if (PyFile_WriteString(msg, f) < 0) {
     914           0 :         return -1;
     915             :     }
     916           2 :     if (PyFile_WriteString(Py_TYPE(value)->tp_name, f) < 0) {
     917           0 :         return -1;
     918             :     }
     919           2 :     if (PyFile_WriteString(" found\n", f) < 0) {
     920           0 :         return -1;
     921             :     }
     922           2 :     return 0;
     923             : }
     924             : 
     925             : static int
     926         477 : print_exception_traceback(struct exception_print_context *ctx, PyObject *value)
     927             : {
     928         477 :     PyObject *f = ctx->file;
     929         477 :     int err = 0;
     930             : 
     931         477 :     PyObject *tb = PyException_GetTraceback(value);
     932         477 :     if (tb && tb != Py_None) {
     933         282 :         const char *header = EXCEPTION_TB_HEADER;
     934         282 :         const char *header_margin = EXC_MARGIN(ctx);
     935         282 :         if (_PyBaseExceptionGroup_Check(value)) {
     936          10 :             header = EXCEPTION_GROUP_TB_HEADER;
     937          10 :             if (ctx->exception_group_depth == 1) {
     938           9 :                 header_margin = "+ ";
     939             :             }
     940             :         }
     941         282 :         err = _PyTraceBack_Print_Indented(
     942         564 :             tb, EXC_INDENT(ctx), EXC_MARGIN(ctx), header_margin, header, f);
     943             :     }
     944         477 :     Py_XDECREF(tb);
     945         477 :     return err;
     946             : }
     947             : 
     948             : static int
     949         477 : print_exception_file_and_line(struct exception_print_context *ctx,
     950             :                               PyObject **value_p)
     951             : {
     952         477 :     PyObject *f = ctx->file;
     953             : 
     954             :     PyObject *tmp;
     955         477 :     int res = _PyObject_LookupAttr(*value_p, &_Py_ID(print_file_and_line), &tmp);
     956         477 :     if (res <= 0) {
     957         411 :         if (res < 0) {
     958           0 :             PyErr_Clear();
     959             :         }
     960         411 :         return 0;
     961             :     }
     962          66 :     Py_DECREF(tmp);
     963             : 
     964             :     PyObject *message, *filename, *text;
     965             :     Py_ssize_t lineno, offset, end_lineno, end_offset;
     966          66 :     if (!parse_syntax_error(*value_p, &message, &filename,
     967             :                             &lineno, &offset,
     968             :                             &end_lineno, &end_offset, &text)) {
     969           5 :         PyErr_Clear();
     970           5 :         return 0;
     971             :     }
     972             : 
     973          61 :     Py_SETREF(*value_p, message);
     974             : 
     975          61 :     PyObject *line = PyUnicode_FromFormat("  File \"%S\", line %zd\n",
     976             :                                           filename, lineno);
     977          61 :     Py_DECREF(filename);
     978          61 :     if (line == NULL) {
     979           0 :         goto error;
     980             :     }
     981          61 :     if (write_indented_margin(ctx, f) < 0) {
     982           0 :         goto error;
     983             :     }
     984          61 :     if (PyFile_WriteObject(line, f, Py_PRINT_RAW) < 0) {
     985           0 :         goto error;
     986             :     }
     987          61 :     Py_CLEAR(line);
     988             : 
     989          61 :     if (text != NULL) {
     990             :         Py_ssize_t line_size;
     991          59 :         const char *error_line = PyUnicode_AsUTF8AndSize(text, &line_size);
     992             :         // If the location of the error spawn multiple lines, we want
     993             :         // to just print the first one and highlight everything until
     994             :         // the end of that one since we don't support multi-line error
     995             :         // messages.
     996          59 :         if (end_lineno > lineno) {
     997           1 :             end_offset = (error_line != NULL) ? line_size : -1;
     998             :         }
     999             :         // Limit the amount of '^' that we can display to
    1000             :         // the size of the text in the source line.
    1001          59 :         if (error_line != NULL && end_offset > line_size + 1) {
    1002           1 :             end_offset = line_size + 1;
    1003             :         }
    1004          59 :         if (print_error_text(f, offset, end_offset, text) < 0) {
    1005           0 :             goto error;
    1006             :         }
    1007          59 :         Py_DECREF(text);
    1008             :     }
    1009          61 :     assert(!PyErr_Occurred());
    1010          61 :     return 0;
    1011             : 
    1012           0 : error:
    1013           0 :     Py_XDECREF(line);
    1014           0 :     Py_XDECREF(text);
    1015           0 :     return -1;
    1016             : }
    1017             : 
    1018             : /* Prints the message line: module.qualname[: str(exc)] */
    1019             : static int
    1020         477 : print_exception_message(struct exception_print_context *ctx, PyObject *type,
    1021             :                         PyObject *value)
    1022             : {
    1023         477 :     PyObject *f = ctx->file;
    1024             : 
    1025         477 :     assert(PyExceptionClass_Check(type));
    1026             : 
    1027         477 :     if (write_indented_margin(ctx, f) < 0) {
    1028          33 :         return -1;
    1029             :     }
    1030         444 :     PyObject *modulename = PyObject_GetAttr(type, &_Py_ID(__module__));
    1031         444 :     if (modulename == NULL || !PyUnicode_Check(modulename)) {
    1032           1 :         Py_XDECREF(modulename);
    1033           1 :         PyErr_Clear();
    1034           1 :         if (PyFile_WriteString("<unknown>.", f) < 0) {
    1035           0 :             return -1;
    1036             :         }
    1037             :     }
    1038             :     else {
    1039         460 :         if (!_PyUnicode_Equal(modulename, &_Py_ID(builtins)) &&
    1040          17 :             !_PyUnicode_Equal(modulename, &_Py_ID(__main__)))
    1041          15 :         {
    1042          15 :             int res = PyFile_WriteObject(modulename, f, Py_PRINT_RAW);
    1043          15 :             Py_DECREF(modulename);
    1044          15 :             if (res < 0) {
    1045           0 :                 return -1;
    1046             :             }
    1047          15 :             if (PyFile_WriteString(".", f) < 0) {
    1048           0 :                 return -1;
    1049             :             }
    1050             :         }
    1051             :         else {
    1052         428 :             Py_DECREF(modulename);
    1053             :         }
    1054             :     }
    1055             : 
    1056         444 :     PyObject *qualname = PyType_GetQualName((PyTypeObject *)type);
    1057         444 :     if (qualname == NULL || !PyUnicode_Check(qualname)) {
    1058           0 :         Py_XDECREF(qualname);
    1059           0 :         PyErr_Clear();
    1060           0 :         if (PyFile_WriteString("<unknown>", f) < 0) {
    1061           0 :             return -1;
    1062             :         }
    1063             :     }
    1064             :     else {
    1065         444 :         int res = PyFile_WriteObject(qualname, f, Py_PRINT_RAW);
    1066         444 :         Py_DECREF(qualname);
    1067         444 :         if (res < 0) {
    1068           0 :             return -1;
    1069             :         }
    1070             :     }
    1071             : 
    1072         444 :     if (Py_IsNone(value)) {
    1073           0 :         return 0;
    1074             :     }
    1075             : 
    1076         444 :     PyObject *s = PyObject_Str(value);
    1077         444 :     if (s == NULL) {
    1078           3 :         PyErr_Clear();
    1079           3 :         if (PyFile_WriteString(": <exception str() failed>", f) < 0) {
    1080           0 :             return -1;
    1081             :         }
    1082             :     }
    1083             :     else {
    1084             :         /* only print colon if the str() of the
    1085             :            object is not the empty string
    1086             :         */
    1087         441 :         if (!PyUnicode_Check(s) || PyUnicode_GetLength(s) != 0) {
    1088         410 :             if (PyFile_WriteString(": ", f) < 0) {
    1089           0 :                 Py_DECREF(s);
    1090           0 :                 return -1;
    1091             :             }
    1092             :         }
    1093         441 :         int res = PyFile_WriteObject(s, f, Py_PRINT_RAW);
    1094         441 :         Py_DECREF(s);
    1095         441 :         if (res < 0) {
    1096           0 :             return -1;
    1097             :         }
    1098             :     }
    1099             : 
    1100         444 :     return 0;
    1101             : }
    1102             : 
    1103             : static int
    1104         444 : print_exception_suggestions(struct exception_print_context *ctx,
    1105             :                             PyObject *value)
    1106             : {
    1107         444 :     PyObject *f = ctx->file;
    1108         444 :     PyObject *suggestions = _Py_Offer_Suggestions(value);
    1109         444 :     if (suggestions) {
    1110             :         // Add a trailer ". Did you mean: (...)?"
    1111          28 :         if (PyFile_WriteString(". Did you mean: '", f) < 0) {
    1112           0 :             goto error;
    1113             :         }
    1114          28 :         if (PyFile_WriteObject(suggestions, f, Py_PRINT_RAW) < 0) {
    1115           0 :             goto error;
    1116             :         }
    1117          28 :         if (PyFile_WriteString("'?", f) < 0) {
    1118           0 :             goto error;
    1119             :         }
    1120          28 :         Py_DECREF(suggestions);
    1121             :     }
    1122         416 :     else if (PyErr_Occurred()) {
    1123           1 :         PyErr_Clear();
    1124             :     }
    1125         444 :     return 0;
    1126           0 : error:
    1127           0 :     Py_XDECREF(suggestions);
    1128           0 :     return -1;
    1129             : }
    1130             : 
    1131             : static int
    1132         444 : print_exception_notes(struct exception_print_context *ctx, PyObject *value)
    1133             : {
    1134         444 :     PyObject *f = ctx->file;
    1135             : 
    1136         444 :     if (!PyExceptionInstance_Check(value)) {
    1137          61 :         return 0;
    1138             :     }
    1139             : 
    1140         383 :     if (!PyObject_HasAttr(value, &_Py_ID(__notes__))) {
    1141         368 :         return 0;
    1142             :     }
    1143          15 :     PyObject *notes = PyObject_GetAttr(value, &_Py_ID(__notes__));
    1144          15 :     if (notes == NULL) {
    1145           0 :         return -1;
    1146             :     }
    1147          15 :     if (!PySequence_Check(notes)) {
    1148           2 :         int res = 0;
    1149           2 :         if (write_indented_margin(ctx, f) < 0) {
    1150           0 :             res = -1;
    1151             :         }
    1152           2 :         PyObject *s = PyObject_Repr(notes);
    1153           2 :         if (s == NULL) {
    1154           1 :             PyErr_Clear();
    1155           1 :             res = PyFile_WriteString("<__notes__ repr() failed>", f);
    1156             :         }
    1157             :         else {
    1158           1 :             res = PyFile_WriteObject(s, f, Py_PRINT_RAW);
    1159           1 :             Py_DECREF(s);
    1160             :         }
    1161           2 :         Py_DECREF(notes);
    1162           2 :         return res;
    1163             :     }
    1164          13 :     Py_ssize_t num_notes = PySequence_Length(notes);
    1165          13 :     PyObject *lines = NULL;
    1166          34 :     for (Py_ssize_t ni = 0; ni < num_notes; ni++) {
    1167          21 :         PyObject *note = PySequence_GetItem(notes, ni);
    1168          21 :         PyObject *note_str = PyObject_Str(note);
    1169          21 :         Py_DECREF(note);
    1170             : 
    1171          21 :         if (note_str == NULL) {
    1172           1 :             PyErr_Clear();
    1173           1 :             if (PyFile_WriteString("<note str() failed>", f) < 0) {
    1174           0 :                 goto error;
    1175             :             }
    1176             :         }
    1177             :         else {
    1178          20 :             lines = PyUnicode_Splitlines(note_str, 1);
    1179          20 :             Py_DECREF(note_str);
    1180             : 
    1181          20 :             if (lines == NULL) {
    1182           0 :                 goto error;
    1183             :             }
    1184             : 
    1185          20 :             Py_ssize_t n = PyList_GET_SIZE(lines);
    1186          49 :             for (Py_ssize_t i = 0; i < n; i++) {
    1187          29 :                 PyObject *line = PyList_GET_ITEM(lines, i);
    1188          29 :                 assert(PyUnicode_Check(line));
    1189          29 :                 if (write_indented_margin(ctx, f) < 0) {
    1190           0 :                     goto error;
    1191             :                 }
    1192          29 :                 if (PyFile_WriteObject(line, f, Py_PRINT_RAW) < 0) {
    1193           0 :                     goto error;
    1194             :                 }
    1195             :             }
    1196          20 :             Py_CLEAR(lines);
    1197             :         }
    1198          21 :         if (PyFile_WriteString("\n", f) < 0) {
    1199           0 :             goto error;
    1200             :         }
    1201             :     }
    1202             : 
    1203          13 :     Py_DECREF(notes);
    1204          13 :     return 0;
    1205           0 : error:
    1206           0 :     Py_XDECREF(lines);
    1207           0 :     Py_DECREF(notes);
    1208           0 :     return -1;
    1209             : }
    1210             : 
    1211             : static int
    1212         479 : print_exception(struct exception_print_context *ctx, PyObject *value)
    1213             : {
    1214         479 :     PyObject *f = ctx->file;
    1215             : 
    1216         479 :     if (!PyExceptionInstance_Check(value)) {
    1217           2 :         return print_exception_invalid_type(ctx, value);
    1218             :     }
    1219             : 
    1220         477 :     Py_INCREF(value);
    1221         477 :     fflush(stdout);
    1222             : 
    1223         477 :     if (print_exception_traceback(ctx, value) < 0) {
    1224           0 :         goto error;
    1225             :     }
    1226             : 
    1227             :     /* grab the type now because value can change below */
    1228         477 :     PyObject *type = (PyObject *) Py_TYPE(value);
    1229             : 
    1230         477 :     if (print_exception_file_and_line(ctx, &value) < 0) {
    1231           0 :         goto error;
    1232             :     }
    1233         477 :     if (print_exception_message(ctx, type, value) < 0) {
    1234          33 :         goto error;
    1235             :     }
    1236         444 :     if (print_exception_suggestions(ctx, value) < 0) {
    1237           0 :         goto error;
    1238             :     }
    1239         444 :     if (PyFile_WriteString("\n", f) < 0) {
    1240           0 :         goto error;
    1241             :     }
    1242         444 :     if (print_exception_notes(ctx, value) < 0) {
    1243           0 :         goto error;
    1244             :     }
    1245             : 
    1246         444 :     Py_DECREF(value);
    1247         444 :     assert(!PyErr_Occurred());
    1248         444 :     return 0;
    1249          33 : error:
    1250          33 :     Py_DECREF(value);
    1251          33 :     return -1;
    1252             : }
    1253             : 
    1254             : static const char cause_message[] =
    1255             :     "The above exception was the direct cause "
    1256             :     "of the following exception:\n";
    1257             : 
    1258             : static const char context_message[] =
    1259             :     "During handling of the above exception, "
    1260             :     "another exception occurred:\n";
    1261             : 
    1262             : static int
    1263             : print_exception_recursive(struct exception_print_context*, PyObject*);
    1264             : 
    1265             : static int
    1266          21 : print_chained(struct exception_print_context* ctx, PyObject *value,
    1267             :               const char * message, const char *tag)
    1268             : {
    1269          21 :     PyObject *f = ctx->file;
    1270             : 
    1271          21 :     if (_Py_EnterRecursiveCall(" in print_chained") < 0) {
    1272           0 :         return -1;
    1273             :     }
    1274          21 :     bool need_close = ctx->need_close;
    1275          21 :     int res = print_exception_recursive(ctx, value);
    1276          21 :     ctx->need_close = need_close;
    1277          21 :     _Py_LeaveRecursiveCall();
    1278          21 :     if (res < 0) {
    1279           0 :         return -1;
    1280             :     }
    1281             : 
    1282          21 :     if (write_indented_margin(ctx, f) < 0) {
    1283           0 :         return -1;
    1284             :     }
    1285          21 :     if (PyFile_WriteString("\n", f) < 0) {
    1286           0 :         return -1;
    1287             :     }
    1288          21 :     if (write_indented_margin(ctx, f) < 0) {
    1289           0 :         return -1;
    1290             :     }
    1291          21 :     if (PyFile_WriteString(message, f) < 0) {
    1292           0 :         return -1;
    1293             :     }
    1294          21 :     if (write_indented_margin(ctx, f) < 0) {
    1295           0 :         return -1;
    1296             :     }
    1297          21 :     if (PyFile_WriteString("\n", f) < 0) {
    1298           0 :         return -1;
    1299             :     }
    1300          21 :     return 0;
    1301             : }
    1302             : 
    1303             : /* Return true if value is in seen or there was a lookup error.
    1304             :  * Return false if lookup succeeded and the item was not found.
    1305             :  * We suppress errors because this makes us err on the side of
    1306             :  * under-printing which is better than over-printing irregular
    1307             :  * exceptions (e.g., unhashable ones).
    1308             :  */
    1309             : static bool
    1310          23 : print_exception_seen_lookup(struct exception_print_context *ctx,
    1311             :                             PyObject *value)
    1312             : {
    1313          23 :     PyObject *check_id = PyLong_FromVoidPtr(value);
    1314          23 :     if (check_id == NULL) {
    1315           0 :         PyErr_Clear();
    1316           0 :         return true;
    1317             :     }
    1318             : 
    1319          23 :     int in_seen = PySet_Contains(ctx->seen, check_id);
    1320          23 :     Py_DECREF(check_id);
    1321          23 :     if (in_seen == -1) {
    1322           0 :         PyErr_Clear();
    1323           0 :         return true;
    1324             :     }
    1325             : 
    1326          23 :     if (in_seen == 1) {
    1327             :         /* value is in seen */
    1328           2 :         return true;
    1329             :     }
    1330          21 :     return false;
    1331             : }
    1332             : 
    1333             : static int
    1334         447 : print_exception_cause_and_context(struct exception_print_context *ctx,
    1335             :                                   PyObject *value)
    1336             : {
    1337         447 :     PyObject *value_id = PyLong_FromVoidPtr(value);
    1338         447 :     if (value_id == NULL || PySet_Add(ctx->seen, value_id) == -1) {
    1339           0 :         PyErr_Clear();
    1340           0 :         Py_XDECREF(value_id);
    1341           0 :         return 0;
    1342             :     }
    1343         447 :     Py_DECREF(value_id);
    1344             : 
    1345         447 :     if (!PyExceptionInstance_Check(value)) {
    1346           2 :         return 0;
    1347             :     }
    1348             : 
    1349         445 :     PyObject *cause = PyException_GetCause(value);
    1350         445 :     if (cause) {
    1351          12 :         int err = 0;
    1352          12 :         if (!print_exception_seen_lookup(ctx, cause)) {
    1353          10 :             err = print_chained(ctx, cause, cause_message, "cause");
    1354             :         }
    1355          12 :         Py_DECREF(cause);
    1356          12 :         return err;
    1357             :     }
    1358         433 :     if (((PyBaseExceptionObject *)value)->suppress_context) {
    1359           2 :         return 0;
    1360             :     }
    1361         431 :     PyObject *context = PyException_GetContext(value);
    1362         431 :     if (context) {
    1363          11 :         int err = 0;
    1364          11 :         if (!print_exception_seen_lookup(ctx, context)) {
    1365          11 :             err = print_chained(ctx, context, context_message, "context");
    1366             :         }
    1367          11 :         Py_DECREF(context);
    1368          11 :         return err;
    1369             :     }
    1370         420 :     return 0;
    1371             : }
    1372             : 
    1373             : static int
    1374          33 : print_exception_group(struct exception_print_context *ctx, PyObject *value)
    1375             : {
    1376          33 :     PyObject *f = ctx->file;
    1377             : 
    1378          33 :     if (ctx->exception_group_depth > ctx->max_group_depth) {
    1379             :         /* depth exceeds limit */
    1380             : 
    1381           2 :         if (write_indented_margin(ctx, f) < 0) {
    1382           0 :             return -1;
    1383             :         }
    1384             : 
    1385           2 :         PyObject *line = PyUnicode_FromFormat("... (max_group_depth is %d)\n",
    1386             :                                               ctx->max_group_depth);
    1387           2 :         if (line == NULL) {
    1388           0 :             return -1;
    1389             :         }
    1390           2 :         int err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
    1391           2 :         Py_DECREF(line);
    1392           2 :         return err;
    1393             :     }
    1394             : 
    1395          31 :     if (ctx->exception_group_depth == 0) {
    1396          12 :         ctx->exception_group_depth += 1;
    1397             :     }
    1398          31 :     print_exception(ctx, value);
    1399             : 
    1400          31 :     PyObject *excs = ((PyBaseExceptionGroupObject *)value)->excs;
    1401          31 :     assert(excs && PyTuple_Check(excs));
    1402          31 :     Py_ssize_t num_excs = PyTuple_GET_SIZE(excs);
    1403          31 :     assert(num_excs > 0);
    1404             :     Py_ssize_t n;
    1405          31 :     if (num_excs <= ctx->max_group_width) {
    1406          30 :         n = num_excs;
    1407             :     }
    1408             :     else {
    1409           1 :         n = ctx->max_group_width + 1;
    1410             :     }
    1411             : 
    1412          31 :     ctx->need_close = false;
    1413         107 :     for (Py_ssize_t i = 0; i < n; i++) {
    1414          76 :         bool last_exc = (i == n - 1);
    1415          76 :         if (last_exc) {
    1416             :             // The closing frame may be added in a recursive call
    1417          31 :             ctx->need_close = true;
    1418             :         }
    1419             : 
    1420          76 :         if (_Py_WriteIndent(EXC_INDENT(ctx), f) < 0) {
    1421           0 :             return -1;
    1422             :         }
    1423          76 :         bool truncated = (i >= ctx->max_group_width);
    1424             :         PyObject *line;
    1425          76 :         if (!truncated) {
    1426          75 :             line = PyUnicode_FromFormat(
    1427             :                 "%s+---------------- %zd ----------------\n",
    1428             :                 (i == 0) ? "+-" : "  ", i + 1);
    1429             :         }
    1430             :         else {
    1431           1 :             line = PyUnicode_FromFormat(
    1432             :                 "%s+---------------- ... ----------------\n",
    1433             :                 (i == 0) ? "+-" : "  ");
    1434             :         }
    1435          76 :         if (line == NULL) {
    1436           0 :             return -1;
    1437             :         }
    1438          76 :         int err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
    1439          76 :         Py_DECREF(line);
    1440          76 :         if (err < 0) {
    1441           0 :             return -1;
    1442             :         }
    1443             : 
    1444          76 :         ctx->exception_group_depth += 1;
    1445          76 :         PyObject *exc = PyTuple_GET_ITEM(excs, i);
    1446             : 
    1447          76 :         if (!truncated) {
    1448          75 :             if (_Py_EnterRecursiveCall(" in print_exception_group") != 0) {
    1449           0 :                 return -1;
    1450             :             }
    1451          75 :             int res = print_exception_recursive(ctx, exc);
    1452          75 :             _Py_LeaveRecursiveCall();
    1453          75 :             if (res < 0) {
    1454           0 :                 return -1;
    1455             :             }
    1456             :         }
    1457             :         else {
    1458           1 :             Py_ssize_t excs_remaining = num_excs - ctx->max_group_width;
    1459             : 
    1460           1 :             if (write_indented_margin(ctx, f) < 0) {
    1461           0 :                 return -1;
    1462             :             }
    1463             : 
    1464           1 :             PyObject *line = PyUnicode_FromFormat(
    1465             :                 "and %zd more exception%s\n",
    1466             :                 excs_remaining, excs_remaining > 1 ? "s" : "");
    1467             : 
    1468           1 :             if (line == NULL) {
    1469           0 :                 return -1;
    1470             :             }
    1471             : 
    1472           1 :             int err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
    1473           1 :             Py_DECREF(line);
    1474           1 :             if (err < 0) {
    1475           0 :                 return -1;
    1476             :             }
    1477             :         }
    1478             : 
    1479          76 :         if (last_exc && ctx->need_close) {
    1480          22 :             if (_Py_WriteIndent(EXC_INDENT(ctx), f) < 0) {
    1481           0 :                 return -1;
    1482             :             }
    1483          22 :             if (PyFile_WriteString(
    1484             :                     "+------------------------------------\n", f) < 0) {
    1485           0 :                 return -1;
    1486             :             }
    1487          22 :             ctx->need_close = false;
    1488             :         }
    1489          76 :         ctx->exception_group_depth -= 1;
    1490             :     }
    1491             : 
    1492          31 :     if (ctx->exception_group_depth == 1) {
    1493          12 :         ctx->exception_group_depth -= 1;
    1494             :     }
    1495          31 :     return 0;
    1496             : }
    1497             : 
    1498             : static int
    1499         481 : print_exception_recursive(struct exception_print_context *ctx, PyObject *value)
    1500             : {
    1501         481 :     if (ctx->seen != NULL) {
    1502             :         /* Exception chaining */
    1503         447 :         if (print_exception_cause_and_context(ctx, value) < 0) {
    1504           0 :             return -1;
    1505             :         }
    1506             :     }
    1507         481 :     if (!_PyBaseExceptionGroup_Check(value)) {
    1508         448 :         if (print_exception(ctx, value) < 0) {
    1509          33 :             return -1;
    1510             :         }
    1511             :     }
    1512          33 :     else if (print_exception_group(ctx, value) < 0) {
    1513           0 :         return -1;
    1514             :     }
    1515         448 :     assert(!PyErr_Occurred());
    1516         448 :     return 0;
    1517             : }
    1518             : 
    1519             : #define PyErr_MAX_GROUP_WIDTH 15
    1520             : #define PyErr_MAX_GROUP_DEPTH 10
    1521             : 
    1522             : void
    1523         385 : _PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *tb)
    1524             : {
    1525         385 :     assert(file != NULL && file != Py_None);
    1526         385 :     if (PyExceptionInstance_Check(value)
    1527         383 :         && tb != NULL && PyTraceBack_Check(tb)) {
    1528             :         /* Put the traceback on the exception, otherwise it won't get
    1529             :            displayed.  See issue #18776. */
    1530         264 :         PyObject *cur_tb = PyException_GetTraceback(value);
    1531         264 :         if (cur_tb == NULL)
    1532           0 :             PyException_SetTraceback(value, tb);
    1533             :         else
    1534         264 :             Py_DECREF(cur_tb);
    1535             :     }
    1536             : 
    1537             :     struct exception_print_context ctx;
    1538         385 :     ctx.file = file;
    1539         385 :     ctx.exception_group_depth = 0;
    1540         385 :     ctx.need_close = false;
    1541         385 :     ctx.max_group_width = PyErr_MAX_GROUP_WIDTH;
    1542         385 :     ctx.max_group_depth = PyErr_MAX_GROUP_DEPTH;
    1543             : 
    1544             :     /* We choose to ignore seen being possibly NULL, and report
    1545             :        at least the main exception (it could be a MemoryError).
    1546             :     */
    1547         385 :     ctx.seen = PySet_New(NULL);
    1548         385 :     if (ctx.seen == NULL) {
    1549          34 :         PyErr_Clear();
    1550             :     }
    1551         385 :     if (print_exception_recursive(&ctx, value) < 0) {
    1552          33 :         PyErr_Clear();
    1553          33 :         _PyObject_Dump(value);
    1554          33 :         fprintf(stderr, "lost sys.stderr\n");
    1555             :     }
    1556         385 :     Py_XDECREF(ctx.seen);
    1557             : 
    1558             :     /* Call file.flush() */
    1559         385 :     PyObject *res = _PyObject_CallMethodNoArgs(file, &_Py_ID(flush));
    1560         385 :     if (!res) {
    1561             :         /* Silently ignore file.flush() error */
    1562           1 :         PyErr_Clear();
    1563             :     }
    1564             :     else {
    1565         384 :         Py_DECREF(res);
    1566             :     }
    1567         385 : }
    1568             : 
    1569             : void
    1570         378 : PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
    1571             : {
    1572         378 :     PyThreadState *tstate = _PyThreadState_GET();
    1573         378 :     PyObject *file = _PySys_GetAttr(tstate, &_Py_ID(stderr));
    1574         378 :     if (file == NULL) {
    1575           0 :         _PyObject_Dump(value);
    1576           0 :         fprintf(stderr, "lost sys.stderr\n");
    1577           0 :         return;
    1578             :     }
    1579         378 :     if (file == Py_None) {
    1580           0 :         return;
    1581             :     }
    1582         378 :     Py_INCREF(file);
    1583         378 :     _PyErr_Display(file, exception, value, tb);
    1584         378 :     Py_DECREF(file);
    1585             : }
    1586             : 
    1587             : PyObject *
    1588       96706 : PyRun_StringFlags(const char *str, int start, PyObject *globals,
    1589             :                   PyObject *locals, PyCompilerFlags *flags)
    1590             : {
    1591       96706 :     PyObject *ret = NULL;
    1592             :     mod_ty mod;
    1593             :     PyArena *arena;
    1594             : 
    1595       96706 :     arena = _PyArena_New();
    1596       96706 :     if (arena == NULL)
    1597           0 :         return NULL;
    1598             : 
    1599             :     _Py_DECLARE_STR(anon_string, "<string>");
    1600       96706 :     mod = _PyParser_ASTFromString(
    1601             :             str, &_Py_STR(anon_string), start, flags, arena);
    1602             : 
    1603       96706 :     if (mod != NULL)
    1604       96193 :         ret = run_mod(mod, &_Py_STR(anon_string), globals, locals, flags, arena);
    1605       96704 :     _PyArena_Free(arena);
    1606       96704 :     return ret;
    1607             : }
    1608             : 
    1609             : 
    1610             : static PyObject *
    1611         324 : pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals,
    1612             :            PyObject *locals, int closeit, PyCompilerFlags *flags)
    1613             : {
    1614         324 :     PyArena *arena = _PyArena_New();
    1615         324 :     if (arena == NULL) {
    1616           0 :         return NULL;
    1617             :     }
    1618             : 
    1619             :     mod_ty mod;
    1620         324 :     mod = _PyParser_ASTFromFile(fp, filename, NULL, start, NULL, NULL,
    1621             :                                 flags, NULL, arena);
    1622             : 
    1623         324 :     if (closeit) {
    1624         310 :         fclose(fp);
    1625             :     }
    1626             : 
    1627             :     PyObject *ret;
    1628         324 :     if (mod != NULL) {
    1629         308 :         ret = run_mod(mod, filename, globals, locals, flags, arena);
    1630             :     }
    1631             :     else {
    1632          16 :         ret = NULL;
    1633             :     }
    1634         324 :     _PyArena_Free(arena);
    1635             : 
    1636         324 :     return ret;
    1637             : }
    1638             : 
    1639             : 
    1640             : PyObject *
    1641           0 : PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,
    1642             :                   PyObject *locals, int closeit, PyCompilerFlags *flags)
    1643             : {
    1644           0 :     PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename);
    1645           0 :     if (filename_obj == NULL) {
    1646           0 :         return NULL;
    1647             :     }
    1648             : 
    1649           0 :     PyObject *res = pyrun_file(fp, filename_obj, start, globals,
    1650             :                                locals, closeit, flags);
    1651           0 :     Py_DECREF(filename_obj);
    1652           0 :     return res;
    1653             : 
    1654             : }
    1655             : 
    1656             : 
    1657             : static void
    1658         387 : flush_io(void)
    1659             : {
    1660             :     PyObject *f, *r;
    1661             :     PyObject *type, *value, *traceback;
    1662             : 
    1663             :     /* Save the current exception */
    1664         387 :     PyErr_Fetch(&type, &value, &traceback);
    1665             : 
    1666         387 :     PyThreadState *tstate = _PyThreadState_GET();
    1667         387 :     f = _PySys_GetAttr(tstate, &_Py_ID(stderr));
    1668         387 :     if (f != NULL) {
    1669         387 :         r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush));
    1670         387 :         if (r)
    1671         387 :             Py_DECREF(r);
    1672             :         else
    1673           0 :             PyErr_Clear();
    1674             :     }
    1675         387 :     f = _PySys_GetAttr(tstate, &_Py_ID(stdout));
    1676         387 :     if (f != NULL) {
    1677         387 :         r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush));
    1678         387 :         if (r)
    1679         387 :             Py_DECREF(r);
    1680             :         else
    1681           0 :             PyErr_Clear();
    1682             :     }
    1683             : 
    1684         387 :     PyErr_Restore(type, value, traceback);
    1685         387 : }
    1686             : 
    1687             : static PyObject *
    1688       96447 : run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, PyObject *locals)
    1689             : {
    1690             :     PyObject *v;
    1691             :     /*
    1692             :      * We explicitly re-initialize _Py_UnhandledKeyboardInterrupt every eval
    1693             :      * _just in case_ someone is calling into an embedded Python where they
    1694             :      * don't care about an uncaught KeyboardInterrupt exception (why didn't they
    1695             :      * leave config.install_signal_handlers set to 0?!?) but then later call
    1696             :      * Py_Main() itself (which _checks_ this flag and dies with a signal after
    1697             :      * its interpreter exits).  We don't want a previous embedded interpreter's
    1698             :      * uncaught exception to trigger an unexplained signal exit from a future
    1699             :      * Py_Main() based one.
    1700             :      */
    1701       96447 :     _Py_UnhandledKeyboardInterrupt = 0;
    1702             : 
    1703             :     /* Set globals['__builtins__'] if it doesn't exist */
    1704       96447 :     if (globals != NULL && _PyDict_GetItemStringWithError(globals, "__builtins__") == NULL) {
    1705           2 :         if (PyErr_Occurred() ||
    1706           1 :             PyDict_SetItemString(globals, "__builtins__",
    1707           1 :                                  tstate->interp->builtins) < 0)
    1708             :         {
    1709           0 :             return NULL;
    1710             :         }
    1711             :     }
    1712             : 
    1713       96447 :     v = PyEval_EvalCode((PyObject*)co, globals, locals);
    1714       96445 :     if (!v && _PyErr_Occurred(tstate) == PyExc_KeyboardInterrupt) {
    1715           0 :         _Py_UnhandledKeyboardInterrupt = 1;
    1716             :     }
    1717       96445 :     return v;
    1718             : }
    1719             : 
    1720             : static PyObject *
    1721       96523 : run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals,
    1722             :             PyCompilerFlags *flags, PyArena *arena)
    1723             : {
    1724       96523 :     PyThreadState *tstate = _PyThreadState_GET();
    1725       96523 :     PyCodeObject *co = _PyAST_Compile(mod, filename, flags, -1, arena);
    1726       96523 :     if (co == NULL)
    1727         104 :         return NULL;
    1728             : 
    1729       96419 :     if (_PySys_Audit(tstate, "exec", "O", co) < 0) {
    1730           0 :         Py_DECREF(co);
    1731           0 :         return NULL;
    1732             :     }
    1733             : 
    1734       96419 :     PyObject *v = run_eval_code_obj(tstate, co, globals, locals);
    1735       96417 :     Py_DECREF(co);
    1736       96417 :     return v;
    1737             : }
    1738             : 
    1739             : static PyObject *
    1740          28 : run_pyc_file(FILE *fp, PyObject *globals, PyObject *locals,
    1741             :              PyCompilerFlags *flags)
    1742             : {
    1743          28 :     PyThreadState *tstate = _PyThreadState_GET();
    1744             :     PyCodeObject *co;
    1745             :     PyObject *v;
    1746             :     long magic;
    1747             :     long PyImport_GetMagicNumber(void);
    1748             : 
    1749          28 :     magic = PyMarshal_ReadLongFromFile(fp);
    1750          28 :     if (magic != PyImport_GetMagicNumber()) {
    1751           0 :         if (!PyErr_Occurred())
    1752           0 :             PyErr_SetString(PyExc_RuntimeError,
    1753             :                        "Bad magic number in .pyc file");
    1754           0 :         goto error;
    1755             :     }
    1756             :     /* Skip the rest of the header. */
    1757          28 :     (void) PyMarshal_ReadLongFromFile(fp);
    1758          28 :     (void) PyMarshal_ReadLongFromFile(fp);
    1759          28 :     (void) PyMarshal_ReadLongFromFile(fp);
    1760          28 :     if (PyErr_Occurred()) {
    1761           0 :         goto error;
    1762             :     }
    1763          28 :     v = PyMarshal_ReadLastObjectFromFile(fp);
    1764          28 :     if (v == NULL || !PyCode_Check(v)) {
    1765           0 :         Py_XDECREF(v);
    1766           0 :         PyErr_SetString(PyExc_RuntimeError,
    1767             :                    "Bad code object in .pyc file");
    1768           0 :         goto error;
    1769             :     }
    1770          28 :     fclose(fp);
    1771          28 :     co = (PyCodeObject *)v;
    1772          28 :     v = run_eval_code_obj(tstate, co, globals, locals);
    1773          28 :     if (v && flags)
    1774           4 :         flags->cf_flags |= (co->co_flags & PyCF_MASK);
    1775          28 :     Py_DECREF(co);
    1776          28 :     return v;
    1777           0 : error:
    1778           0 :     fclose(fp);
    1779           0 :     return NULL;
    1780             : }
    1781             : 
    1782             : PyObject *
    1783       30344 : Py_CompileStringObject(const char *str, PyObject *filename, int start,
    1784             :                        PyCompilerFlags *flags, int optimize)
    1785             : {
    1786             :     PyCodeObject *co;
    1787             :     mod_ty mod;
    1788       30344 :     PyArena *arena = _PyArena_New();
    1789       30344 :     if (arena == NULL)
    1790           0 :         return NULL;
    1791             : 
    1792       30344 :     mod = _PyParser_ASTFromString(str, filename, start, flags, arena);
    1793       30344 :     if (mod == NULL) {
    1794        1704 :         _PyArena_Free(arena);
    1795        1704 :         return NULL;
    1796             :     }
    1797       28640 :     if (flags && (flags->cf_flags & PyCF_ONLY_AST)) {
    1798       10978 :         PyObject *result = PyAST_mod2obj(mod);
    1799       10978 :         _PyArena_Free(arena);
    1800       10978 :         return result;
    1801             :     }
    1802       17662 :     co = _PyAST_Compile(mod, filename, flags, optimize, arena);
    1803       17662 :     _PyArena_Free(arena);
    1804       17662 :     return (PyObject *)co;
    1805             : }
    1806             : 
    1807             : PyObject *
    1808           5 : Py_CompileStringExFlags(const char *str, const char *filename_str, int start,
    1809             :                         PyCompilerFlags *flags, int optimize)
    1810             : {
    1811             :     PyObject *filename, *co;
    1812           5 :     filename = PyUnicode_DecodeFSDefault(filename_str);
    1813           5 :     if (filename == NULL)
    1814           0 :         return NULL;
    1815           5 :     co = Py_CompileStringObject(str, filename, start, flags, optimize);
    1816           5 :     Py_DECREF(filename);
    1817           5 :     return co;
    1818             : }
    1819             : 
    1820             : const char *
    1821      125271 : _Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, PyObject **cmd_copy)
    1822             : {
    1823             :     const char *str;
    1824             :     Py_ssize_t size;
    1825             :     Py_buffer view;
    1826             : 
    1827      125271 :     *cmd_copy = NULL;
    1828      125271 :     if (PyUnicode_Check(cmd)) {
    1829      113401 :         cf->cf_flags |= PyCF_IGNORE_COOKIE;
    1830      113401 :         str = PyUnicode_AsUTF8AndSize(cmd, &size);
    1831      113401 :         if (str == NULL)
    1832           0 :             return NULL;
    1833             :     }
    1834       11870 :     else if (PyBytes_Check(cmd)) {
    1835       11860 :         str = PyBytes_AS_STRING(cmd);
    1836       11860 :         size = PyBytes_GET_SIZE(cmd);
    1837             :     }
    1838          10 :     else if (PyByteArray_Check(cmd)) {
    1839           0 :         str = PyByteArray_AS_STRING(cmd);
    1840           0 :         size = PyByteArray_GET_SIZE(cmd);
    1841             :     }
    1842          10 :     else if (PyObject_GetBuffer(cmd, &view, PyBUF_SIMPLE) == 0) {
    1843             :         /* Copy to NUL-terminated buffer. */
    1844          14 :         *cmd_copy = PyBytes_FromStringAndSize(
    1845           7 :             (const char *)view.buf, view.len);
    1846           7 :         PyBuffer_Release(&view);
    1847           7 :         if (*cmd_copy == NULL) {
    1848           0 :             return NULL;
    1849             :         }
    1850           7 :         str = PyBytes_AS_STRING(*cmd_copy);
    1851           7 :         size = PyBytes_GET_SIZE(*cmd_copy);
    1852             :     }
    1853             :     else {
    1854           3 :         PyErr_Format(PyExc_TypeError,
    1855             :             "%s() arg 1 must be a %s object",
    1856             :             funcname, what);
    1857           3 :         return NULL;
    1858             :     }
    1859             : 
    1860      125268 :     if (strlen(str) != (size_t)size) {
    1861           4 :         PyErr_SetString(PyExc_ValueError,
    1862             :             "source code string cannot contain null bytes");
    1863           4 :         Py_CLEAR(*cmd_copy);
    1864           4 :         return NULL;
    1865             :     }
    1866      125264 :     return str;
    1867             : }
    1868             : 
    1869             : #if defined(USE_STACKCHECK)
    1870             : #if defined(WIN32) && defined(_MSC_VER)
    1871             : 
    1872             : /* Stack checking for Microsoft C */
    1873             : 
    1874             : #include <malloc.h>
    1875             : #include <excpt.h>
    1876             : 
    1877             : /*
    1878             :  * Return non-zero when we run out of memory on the stack; zero otherwise.
    1879             :  */
    1880             : int
    1881             : PyOS_CheckStack(void)
    1882             : {
    1883             :     __try {
    1884             :         /* alloca throws a stack overflow exception if there's
    1885             :            not enough space left on the stack */
    1886             :         alloca(PYOS_STACK_MARGIN * sizeof(void*));
    1887             :         return 0;
    1888             :     } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ?
    1889             :                     EXCEPTION_EXECUTE_HANDLER :
    1890             :             EXCEPTION_CONTINUE_SEARCH) {
    1891             :         int errcode = _resetstkoflw();
    1892             :         if (errcode == 0)
    1893             :         {
    1894             :             Py_FatalError("Could not reset the stack!");
    1895             :         }
    1896             :     }
    1897             :     return 1;
    1898             : }
    1899             : 
    1900             : #endif /* WIN32 && _MSC_VER */
    1901             : 
    1902             : /* Alternate implementations can be added here... */
    1903             : 
    1904             : #endif /* USE_STACKCHECK */
    1905             : 
    1906             : /* Deprecated C API functions still provided for binary compatibility */
    1907             : 
    1908             : #undef PyRun_AnyFile
    1909             : PyAPI_FUNC(int)
    1910           0 : PyRun_AnyFile(FILE *fp, const char *name)
    1911             : {
    1912           0 :     return PyRun_AnyFileExFlags(fp, name, 0, NULL);
    1913             : }
    1914             : 
    1915             : #undef PyRun_AnyFileEx
    1916             : PyAPI_FUNC(int)
    1917           0 : PyRun_AnyFileEx(FILE *fp, const char *name, int closeit)
    1918             : {
    1919           0 :     return PyRun_AnyFileExFlags(fp, name, closeit, NULL);
    1920             : }
    1921             : 
    1922             : #undef PyRun_AnyFileFlags
    1923             : PyAPI_FUNC(int)
    1924           0 : PyRun_AnyFileFlags(FILE *fp, const char *name, PyCompilerFlags *flags)
    1925             : {
    1926           0 :     return PyRun_AnyFileExFlags(fp, name, 0, flags);
    1927             : }
    1928             : 
    1929             : #undef PyRun_File
    1930             : PyAPI_FUNC(PyObject *)
    1931           0 : PyRun_File(FILE *fp, const char *p, int s, PyObject *g, PyObject *l)
    1932             : {
    1933           0 :     return PyRun_FileExFlags(fp, p, s, g, l, 0, NULL);
    1934             : }
    1935             : 
    1936             : #undef PyRun_FileEx
    1937             : PyAPI_FUNC(PyObject *)
    1938           0 : PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, int c)
    1939             : {
    1940           0 :     return PyRun_FileExFlags(fp, p, s, g, l, c, NULL);
    1941             : }
    1942             : 
    1943             : #undef PyRun_FileFlags
    1944             : PyAPI_FUNC(PyObject *)
    1945           0 : PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l,
    1946             :                 PyCompilerFlags *flags)
    1947             : {
    1948           0 :     return PyRun_FileExFlags(fp, p, s, g, l, 0, flags);
    1949             : }
    1950             : 
    1951             : #undef PyRun_SimpleFile
    1952             : PyAPI_FUNC(int)
    1953           0 : PyRun_SimpleFile(FILE *f, const char *p)
    1954             : {
    1955           0 :     return PyRun_SimpleFileExFlags(f, p, 0, NULL);
    1956             : }
    1957             : 
    1958             : #undef PyRun_SimpleFileEx
    1959             : PyAPI_FUNC(int)
    1960           0 : PyRun_SimpleFileEx(FILE *f, const char *p, int c)
    1961             : {
    1962           0 :     return PyRun_SimpleFileExFlags(f, p, c, NULL);
    1963             : }
    1964             : 
    1965             : 
    1966             : #undef PyRun_String
    1967             : PyAPI_FUNC(PyObject *)
    1968           0 : PyRun_String(const char *str, int s, PyObject *g, PyObject *l)
    1969             : {
    1970           0 :     return PyRun_StringFlags(str, s, g, l, NULL);
    1971             : }
    1972             : 
    1973             : #undef PyRun_SimpleString
    1974             : PyAPI_FUNC(int)
    1975           0 : PyRun_SimpleString(const char *s)
    1976             : {
    1977           0 :     return PyRun_SimpleStringFlags(s, NULL);
    1978             : }
    1979             : 
    1980             : #undef Py_CompileString
    1981             : PyAPI_FUNC(PyObject *)
    1982           0 : Py_CompileString(const char *str, const char *p, int s)
    1983             : {
    1984           0 :     return Py_CompileStringExFlags(str, p, s, NULL, -1);
    1985             : }
    1986             : 
    1987             : #undef Py_CompileStringFlags
    1988             : PyAPI_FUNC(PyObject *)
    1989           0 : Py_CompileStringFlags(const char *str, const char *p, int s,
    1990             :                       PyCompilerFlags *flags)
    1991             : {
    1992           0 :     return Py_CompileStringExFlags(str, p, s, flags, -1);
    1993             : }
    1994             : 
    1995             : #undef PyRun_InteractiveOne
    1996             : PyAPI_FUNC(int)
    1997           0 : PyRun_InteractiveOne(FILE *f, const char *p)
    1998             : {
    1999           0 :     return PyRun_InteractiveOneFlags(f, p, NULL);
    2000             : }
    2001             : 
    2002             : #undef PyRun_InteractiveLoop
    2003             : PyAPI_FUNC(int)
    2004           0 : PyRun_InteractiveLoop(FILE *f, const char *p)
    2005             : {
    2006           0 :     return PyRun_InteractiveLoopFlags(f, p, NULL);
    2007             : }
    2008             : 
    2009             : #ifdef __cplusplus
    2010             : }
    2011             : #endif

Generated by: LCOV version 1.14