summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Python/pythonrun.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tools/python3/Python/pythonrun.c')
-rw-r--r--contrib/tools/python3/Python/pythonrun.c1123
1 files changed, 418 insertions, 705 deletions
diff --git a/contrib/tools/python3/Python/pythonrun.c b/contrib/tools/python3/Python/pythonrun.c
index 89287bace08..c4a1275eb52 100644
--- a/contrib/tools/python3/Python/pythonrun.c
+++ b/contrib/tools/python3/Python/pythonrun.c
@@ -10,17 +10,18 @@
#include "Python.h"
-#include "pycore_ast.h" // PyAST_mod2obj
-#include "pycore_ceval.h" // _Py_EnterRecursiveCall
+#include "pycore_ast.h" // PyAST_mod2obj()
+#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
#include "pycore_compile.h" // _PyAST_Compile()
#include "pycore_interp.h" // PyInterpreterState.importlib
#include "pycore_object.h" // _PyDebug_PrintTotalRefs()
#include "pycore_parser.h" // _PyParser_ASTFromString()
-#include "pycore_pyerrors.h" // _PyErr_GetRaisedException, _Py_Offer_Suggestions
-#include "pycore_pylifecycle.h" // _Py_UnhandledKeyboardInterrupt
+#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
+#include "pycore_pylifecycle.h" // _Py_FdIsInteractive()
#include "pycore_pystate.h" // _PyInterpreterState_GET()
+#include "pycore_pythonrun.h" // export _PyRun_InteractiveLoopObject()
#include "pycore_sysmodule.h" // _PySys_Audit()
-#include "pycore_traceback.h" // _PyTraceBack_Print_Indented()
+#include "pycore_traceback.h" // _PyTraceBack_Print()
#include "errcode.h" // E_EOF
#include "marshal.h" // PyMarshal_ReadLongFromFile()
@@ -36,22 +37,20 @@
# include "windows.h"
#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Forward */
static void flush_io(void);
static PyObject *run_mod(mod_ty, PyObject *, PyObject *, PyObject *,
- PyCompilerFlags *, PyArena *);
+ PyCompilerFlags *, PyArena *, PyObject*, int);
static PyObject *run_pyc_file(FILE *, PyObject *, PyObject *,
PyCompilerFlags *);
static int PyRun_InteractiveOneObjectEx(FILE *, PyObject *, PyCompilerFlags *);
static PyObject* pyrun_file(FILE *fp, PyObject *filename, int start,
PyObject *globals, PyObject *locals, int closeit,
PyCompilerFlags *flags);
-
+static PyObject *
+_PyRun_StringFlagsWithName(const char *str, PyObject* name, int start,
+ PyObject *globals, PyObject *locals, PyCompilerFlags *flags,
+ int generate_new_source);
int
_PyRun_AnyFileObject(FILE *fp, PyObject *filename, int closeit,
@@ -84,13 +83,11 @@ _PyRun_AnyFileObject(FILE *fp, PyObject *filename, int closeit,
return res;
}
-
-/* Parse input from a file and execute it */
int
PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit,
PyCompilerFlags *flags)
{
- PyObject *filename_obj;
+ PyObject *filename_obj = NULL;
if (filename != NULL) {
filename_obj = PyUnicode_DecodeFSDefault(filename);
if (filename_obj == NULL) {
@@ -98,9 +95,6 @@ PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit,
return -1;
}
}
- else {
- filename_obj = NULL;
- }
int res = _PyRun_AnyFileObject(fp, filename_obj, closeit, flags);
Py_XDECREF(filename_obj);
return res;
@@ -197,98 +191,160 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flag
}
-/* A PyRun_InteractiveOneObject() auxiliary function that does not print the
- * error on failure. */
+// Call _PyParser_ASTFromFile() with sys.stdin.encoding, sys.ps1 and sys.ps2
static int
-PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename,
- PyCompilerFlags *flags)
+pyrun_one_parse_ast(FILE *fp, PyObject *filename,
+ PyCompilerFlags *flags, PyArena *arena,
+ mod_ty *pmod, PyObject** interactive_src)
{
- PyObject *m, *d, *v, *w, *oenc = NULL;
- mod_ty mod;
- PyArena *arena;
- const char *ps1 = "", *ps2 = "", *enc = NULL;
- int errcode = 0;
-
+ // Get sys.stdin.encoding (as UTF-8)
+ PyObject *attr;
+ PyObject *encoding_obj = NULL;
+ const char *encoding = NULL;
if (fp == stdin) {
- /* Fetch encoding from sys.stdin if possible. */
- if (_PySys_GetOptionalAttr(&_Py_ID(stdin), &v) < 0) {
- return -1;
+ if (_PySys_GetOptionalAttr(&_Py_ID(stdin), &attr) < 0) {
+ PyErr_Clear();
}
- if (v && v != Py_None) {
- oenc = PyObject_GetAttr(v, &_Py_ID(encoding));
- if (oenc)
- enc = PyUnicode_AsUTF8(oenc);
- if (!enc)
+ else if (attr != NULL && attr != Py_None) {
+ if (PyObject_GetOptionalAttr(attr, &_Py_ID(encoding), &encoding_obj) < 0) {
PyErr_Clear();
+ }
+ else if (encoding_obj && PyUnicode_Check(encoding_obj)) {
+ encoding = PyUnicode_AsUTF8(encoding_obj);
+ if (!encoding) {
+ PyErr_Clear();
+ }
+ }
}
- Py_XDECREF(v);
+ Py_XDECREF(attr);
}
- if (_PySys_GetOptionalAttr(&_Py_ID(ps1), &v) < 0) {
- Py_XDECREF(oenc);
- return -1;
+
+ // Get sys.ps1 (as UTF-8)
+ PyObject *ps1_obj = NULL;
+ const char *ps1 = "";
+ if (_PySys_GetOptionalAttr(&_Py_ID(ps1), &attr) < 0) {
+ PyErr_Clear();
}
- if (v != NULL) {
- Py_SETREF(v, PyObject_Str(v));
- if (v == NULL)
+ else if (attr != NULL) {
+ ps1_obj = PyObject_Str(attr);
+ Py_DECREF(attr);
+ if (ps1_obj == NULL) {
PyErr_Clear();
- else if (PyUnicode_Check(v)) {
- ps1 = PyUnicode_AsUTF8(v);
+ }
+ else if (PyUnicode_Check(ps1_obj)) {
+ ps1 = PyUnicode_AsUTF8(ps1_obj);
if (ps1 == NULL) {
PyErr_Clear();
ps1 = "";
}
}
}
- if (_PySys_GetOptionalAttr(&_Py_ID(ps2), &w) < 0) {
- Py_XDECREF(oenc);
- return -1;
+
+ // Get sys.ps2 (as UTF-8)
+ PyObject *ps2_obj = NULL;
+ const char *ps2 = "";
+ if (_PySys_GetOptionalAttr(&_Py_ID(ps2), &attr) < 0) {
+ PyErr_Clear();
}
- if (w != NULL) {
- Py_SETREF(w, PyObject_Str(w));
- if (w == NULL)
+ else if (attr != NULL) {
+ ps2_obj = PyObject_Str(attr);
+ Py_DECREF(attr);
+ if (ps2_obj == NULL) {
PyErr_Clear();
- else if (PyUnicode_Check(w)) {
- ps2 = PyUnicode_AsUTF8(w);
+ }
+ else if (PyUnicode_Check(ps2_obj)) {
+ ps2 = PyUnicode_AsUTF8(ps2_obj);
if (ps2 == NULL) {
PyErr_Clear();
ps2 = "";
}
}
}
- arena = _PyArena_New();
- if (arena == NULL) {
- Py_XDECREF(v);
- Py_XDECREF(w);
- Py_XDECREF(oenc);
- return -1;
- }
- mod = _PyParser_ASTFromFile(fp, filename, enc, Py_single_input,
- ps1, ps2, flags, &errcode, arena);
+ int errcode = 0;
+ *pmod = _PyParser_InteractiveASTFromFile(fp, filename, encoding,
+ Py_single_input, ps1, ps2,
+ flags, &errcode, interactive_src, arena);
+ Py_XDECREF(ps1_obj);
+ Py_XDECREF(ps2_obj);
+ Py_XDECREF(encoding_obj);
- Py_XDECREF(v);
- Py_XDECREF(w);
- Py_XDECREF(oenc);
- if (mod == NULL) {
- _PyArena_Free(arena);
+ if (*pmod == NULL) {
if (errcode == E_EOF) {
PyErr_Clear();
return E_EOF;
}
return -1;
}
- m = PyImport_AddModuleObject(&_Py_ID(__main__));
- if (m == NULL) {
+ return 0;
+}
+
+
+/* A PyRun_InteractiveOneObject() auxiliary function that does not print the
+ * error on failure. */
+static int
+PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename,
+ PyCompilerFlags *flags)
+{
+ PyArena *arena = _PyArena_New();
+ if (arena == NULL) {
+ return -1;
+ }
+
+ mod_ty mod;
+ PyObject *interactive_src;
+ int parse_res = pyrun_one_parse_ast(fp, filename, flags, arena, &mod, &interactive_src);
+ if (parse_res != 0) {
+ _PyArena_Free(arena);
+ return parse_res;
+ }
+
+ PyObject *main_module = PyImport_AddModuleRef("__main__");
+ if (main_module == NULL) {
_PyArena_Free(arena);
return -1;
}
- d = PyModule_GetDict(m);
- v = run_mod(mod, filename, d, d, flags, arena);
+ PyObject *main_dict = PyModule_GetDict(main_module); // borrowed ref
+
+ PyObject *res = run_mod(mod, filename, main_dict, main_dict, flags, arena, interactive_src, 1);
+ Py_INCREF(interactive_src);
_PyArena_Free(arena);
- if (v == NULL) {
+ Py_DECREF(main_module);
+ if (res == NULL) {
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *exc = _PyErr_GetRaisedException(tstate);
+ if (PyType_IsSubtype(Py_TYPE(exc),
+ (PyTypeObject *) PyExc_SyntaxError))
+ {
+ /* fix "text" attribute */
+ assert(interactive_src != NULL);
+ PyObject *xs = PyUnicode_Splitlines(interactive_src, 1);
+ if (xs == NULL) {
+ goto error;
+ }
+ PyObject *exc_lineno = PyObject_GetAttr(exc, &_Py_ID(lineno));
+ if (exc_lineno == NULL) {
+ Py_DECREF(xs);
+ goto error;
+ }
+ int n = PyLong_AsInt(exc_lineno);
+ Py_DECREF(exc_lineno);
+ if (n <= 0 || n > PyList_GET_SIZE(xs)) {
+ Py_DECREF(xs);
+ goto error;
+ }
+ PyObject *line = PyList_GET_ITEM(xs, n - 1);
+ PyObject_SetAttr(exc, &_Py_ID(text), line);
+ Py_DECREF(xs);
+ }
+error:
+ Py_DECREF(interactive_src);
+ _PyErr_SetRaisedException(tstate, exc);
return -1;
}
- Py_DECREF(v);
+ Py_DECREF(interactive_src);
+ Py_DECREF(res);
+
flush_io();
return 0;
}
@@ -402,22 +458,23 @@ int
_PyRun_SimpleFileObject(FILE *fp, PyObject *filename, int closeit,
PyCompilerFlags *flags)
{
- PyObject *m, *d, *v;
- int set_file_name = 0, ret = -1;
+ int ret = -1;
- m = PyImport_AddModule("__main__");
- if (m == NULL)
+ PyObject *main_module = PyImport_AddModuleRef("__main__");
+ if (main_module == NULL)
return -1;
- Py_INCREF(m);
- d = PyModule_GetDict(m);
- if (_PyDict_GetItemStringWithError(d, "__file__") == NULL) {
- if (PyErr_Occurred()) {
- goto done;
- }
- if (PyDict_SetItemString(d, "__file__", filename) < 0) {
+ PyObject *dict = PyModule_GetDict(main_module); // borrowed ref
+
+ int set_file_name = 0;
+ int has_file = PyDict_ContainsString(dict, "__file__");
+ if (has_file < 0) {
+ goto done;
+ }
+ if (!has_file) {
+ if (PyDict_SetItemString(dict, "__file__", filename) < 0) {
goto done;
}
- if (PyDict_SetItemString(d, "__cached__", Py_None) < 0) {
+ if (PyDict_SetItemString(dict, "__cached__", Py_None) < 0) {
goto done;
}
set_file_name = 1;
@@ -428,6 +485,7 @@ _PyRun_SimpleFileObject(FILE *fp, PyObject *filename, int closeit,
goto done;
}
+ PyObject *v;
if (pyc) {
FILE *pyc_fp;
/* Try to run a pyc file. First, re-open in binary */
@@ -441,42 +499,43 @@ _PyRun_SimpleFileObject(FILE *fp, PyObject *filename, int closeit,
goto done;
}
- if (set_main_loader(d, filename, "SourcelessFileLoader") < 0) {
+ if (set_main_loader(dict, filename, "SourcelessFileLoader") < 0) {
fprintf(stderr, "python: failed to set __main__.__loader__\n");
ret = -1;
fclose(pyc_fp);
goto done;
}
- v = run_pyc_file(pyc_fp, d, d, flags);
+ v = run_pyc_file(pyc_fp, dict, dict, flags);
} else {
/* When running from stdin, leave __main__.__loader__ alone */
- if (PyUnicode_CompareWithASCIIString(filename, "<stdin>") != 0 &&
- set_main_loader(d, filename, "SourceFileLoader") < 0) {
+ if ((!PyUnicode_Check(filename) || !PyUnicode_EqualToUTF8(filename, "<stdin>")) &&
+ set_main_loader(dict, filename, "SourceFileLoader") < 0) {
fprintf(stderr, "python: failed to set __main__.__loader__\n");
ret = -1;
goto done;
}
- v = pyrun_file(fp, filename, Py_file_input, d, d,
+ v = pyrun_file(fp, filename, Py_file_input, dict, dict,
closeit, flags);
}
flush_io();
if (v == NULL) {
- Py_CLEAR(m);
+ Py_CLEAR(main_module);
PyErr_Print();
goto done;
}
Py_DECREF(v);
ret = 0;
+
done:
if (set_file_name) {
- if (PyDict_DelItemString(d, "__file__")) {
- PyErr_Clear();
+ if (PyDict_PopString(dict, "__file__", NULL) < 0) {
+ PyErr_Print();
}
- if (PyDict_DelItemString(d, "__cached__")) {
- PyErr_Clear();
+ if (PyDict_PopString(dict, "__cached__", NULL) < 0) {
+ PyErr_Print();
}
}
- Py_XDECREF(m);
+ Py_XDECREF(main_module);
return ret;
}
@@ -496,214 +555,65 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
int
-PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
-{
- PyObject *m, *d, *v;
- m = PyImport_AddModule("__main__");
- if (m == NULL)
+_PyRun_SimpleStringFlagsWithName(const char *command, const char* name, PyCompilerFlags *flags) {
+ PyObject *main_module = PyImport_AddModuleRef("__main__");
+ if (main_module == NULL) {
return -1;
- d = PyModule_GetDict(m);
- v = PyRun_StringFlags(command, Py_file_input, d, d, flags);
- if (v == NULL) {
- PyErr_Print();
- return -1;
- }
- Py_DECREF(v);
- return 0;
-}
-
-static int
-parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename,
- Py_ssize_t *lineno, Py_ssize_t *offset,
- Py_ssize_t* end_lineno, Py_ssize_t* end_offset,
- PyObject **text)
-{
- Py_ssize_t hold;
- PyObject *v;
-
- *message = NULL;
- *filename = NULL;
-
- /* new style errors. `err' is an instance */
- *message = PyObject_GetAttr(err, &_Py_ID(msg));
- if (!*message)
- goto finally;
-
- v = PyObject_GetAttr(err, &_Py_ID(filename));
- if (!v)
- goto finally;
- if (v == Py_None) {
- Py_DECREF(v);
- _Py_DECLARE_STR(anon_string, "<string>");
- *filename = Py_NewRef(&_Py_STR(anon_string));
- }
- else {
- *filename = v;
}
+ PyObject *dict = PyModule_GetDict(main_module); // borrowed ref
- v = PyObject_GetAttr(err, &_Py_ID(lineno));
- if (!v)
- goto finally;
- hold = PyLong_AsSsize_t(v);
- Py_DECREF(v);
- if (hold < 0 && PyErr_Occurred())
- goto finally;
- *lineno = hold;
-
- v = PyObject_GetAttr(err, &_Py_ID(offset));
- if (!v)
- goto finally;
- if (v == Py_None) {
- *offset = -1;
- Py_DECREF(v);
+ PyObject *res = NULL;
+ if (name == NULL) {
+ res = PyRun_StringFlags(command, Py_file_input, dict, dict, flags);
} else {
- hold = PyLong_AsSsize_t(v);
- Py_DECREF(v);
- if (hold < 0 && PyErr_Occurred())
- goto finally;
- *offset = hold;
- }
-
- v = PyObject_GetAttr(err, &_Py_ID(end_lineno));
- if (!v) {
- PyErr_Clear();
- *end_lineno = *lineno;
- }
- else if (v == Py_None) {
- *end_lineno = *lineno;
- Py_DECREF(v);
- } else {
- hold = PyLong_AsSsize_t(v);
- Py_DECREF(v);
- if (hold < 0 && PyErr_Occurred())
- goto finally;
- *end_lineno = hold;
- }
-
- v = PyObject_GetAttr(err, &_Py_ID(end_offset));
- if (!v) {
- PyErr_Clear();
- *end_offset = -1;
- }
- else if (v == Py_None) {
- *end_offset = -1;
- Py_DECREF(v);
- } else {
- hold = PyLong_AsSsize_t(v);
- Py_DECREF(v);
- if (hold < 0 && PyErr_Occurred())
- goto finally;
- *end_offset = hold;
- }
-
- v = PyObject_GetAttr(err, &_Py_ID(text));
- if (!v)
- goto finally;
- if (v == Py_None) {
- Py_DECREF(v);
- *text = NULL;
+ PyObject* the_name = PyUnicode_FromString(name);
+ if (!the_name) {
+ PyErr_Print();
+ return -1;
+ }
+ res = _PyRun_StringFlagsWithName(command, the_name, Py_file_input, dict, dict, flags, 0);
+ Py_DECREF(the_name);
}
- else {
- *text = v;
+ Py_DECREF(main_module);
+ if (res == NULL) {
+ PyErr_Print();
+ return -1;
}
- return 1;
-finally:
- Py_XDECREF(*message);
- Py_XDECREF(*filename);
+ Py_DECREF(res);
return 0;
}
-static int
-print_error_text(PyObject *f, Py_ssize_t offset, Py_ssize_t end_offset,
- PyObject *text_obj)
+int
+PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
{
- size_t caret_repetitions = (end_offset > 0 && end_offset > offset) ?
- end_offset - offset : 1;
-
- /* Convert text to a char pointer; return if error */
- const char *text = PyUnicode_AsUTF8(text_obj);
- if (text == NULL) {
- return -1;
- }
-
- /* Convert offset from 1-based to 0-based */
- offset--;
-
- /* Strip leading whitespace from text, adjusting offset as we go */
- while (*text == ' ' || *text == '\t' || *text == '\f') {
- text++;
- offset--;
- }
-
- /* Calculate text length excluding trailing newline */
- Py_ssize_t len = strlen(text);
- if (len > 0 && text[len-1] == '\n') {
- len--;
- }
-
- /* Clip offset to at most len */
- if (offset > len) {
- offset = len;
- }
-
- /* Skip past newlines embedded in text */
- for (;;) {
- const char *nl = strchr(text, '\n');
- if (nl == NULL) {
- break;
- }
- Py_ssize_t inl = nl - text;
- if (inl >= offset) {
- break;
- }
- inl += 1;
- text += inl;
- len -= inl;
- offset -= (int)inl;
- }
-
- /* Print text */
- if (PyFile_WriteString(" ", f) < 0) {
- return -1;
- }
- if (PyFile_WriteString(text, f) < 0) {
- return -1;
- }
-
- /* Make sure there's a newline at the end */
- if (text[len] != '\n') {
- if (PyFile_WriteString("\n", f) < 0) {
- return -1;
- }
- }
-
- /* Don't print caret if it points to the left of the text */
- if (offset < 0) {
- return 0;
- }
+ return _PyRun_SimpleStringFlagsWithName(command, NULL, flags);
+}
- /* Write caret line */
- if (PyFile_WriteString(" ", f) < 0) {
- return -1;
- }
- while (--offset >= 0) {
- if (PyFile_WriteString(" ", f) < 0) {
- return -1;
- }
- }
- for (size_t caret_iter=0; caret_iter < caret_repetitions ; caret_iter++) {
- if (PyFile_WriteString("^", f) < 0) {
- return -1;
+static int
+parse_exit_code(PyObject *code, int *exitcode_p)
+{
+ if (PyLong_Check(code)) {
+ // gh-125842: Use a long long to avoid an overflow error when `long`
+ // is 32-bit. We still truncate the result to an int.
+ int exitcode = (int)PyLong_AsLongLong(code);
+ if (exitcode == -1 && PyErr_Occurred()) {
+ // On overflow or other error, clear the exception and use -1
+ // as the exit code to match historical Python behavior.
+ PyErr_Clear();
+ *exitcode_p = -1;
+ return 1;
}
+ *exitcode_p = exitcode;
+ return 1;
}
- if (PyFile_WriteString("\n", f) < 0) {
- return -1;
+ else if (code == Py_None) {
+ *exitcode_p = 0;
+ return 1;
}
return 0;
}
-
int
_Py_HandleSystemExit(int *exitcode_p)
{
@@ -720,51 +630,43 @@ _Py_HandleSystemExit(int *exitcode_p)
fflush(stdout);
- int exitcode = 0;
-
PyObject *exc = PyErr_GetRaisedException();
- if (exc == NULL) {
- goto done;
- }
- assert(PyExceptionInstance_Check(exc));
+ assert(exc != NULL && PyExceptionInstance_Check(exc));
- /* The error code should be in the `code' attribute. */
PyObject *code = PyObject_GetAttr(exc, &_Py_ID(code));
- if (code) {
+ if (code == NULL) {
+ // If the exception has no 'code' attribute, print the exception below
+ PyErr_Clear();
+ }
+ else if (parse_exit_code(code, exitcode_p)) {
+ Py_DECREF(code);
+ Py_CLEAR(exc);
+ return 1;
+ }
+ else {
+ // If code is not an int or None, print it below
Py_SETREF(exc, code);
- if (exc == Py_None) {
- goto done;
- }
}
- /* If we failed to dig out the 'code' attribute,
- * just let the else clause below print the error.
- */
- if (PyLong_Check(exc)) {
- exitcode = (int)PyLong_AsLong(exc);
+ PyObject *sys_stderr;
+ if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &sys_stderr) < 0) {
+ PyErr_Clear();
+ }
+ else if (sys_stderr != NULL && sys_stderr != Py_None) {
+ if (PyFile_WriteObject(exc, sys_stderr, Py_PRINT_RAW) < 0) {
+ PyErr_Clear();
+ }
}
else {
- PyObject *sys_stderr;
- (void) _PySys_GetOptionalAttr(&_Py_ID(stderr), &sys_stderr);
- /* We clear the exception here to avoid triggering the assertion
- * in PyObject_Str that ensures it won't silently lose exception
- * details.
- */
- PyErr_Clear();
- if (sys_stderr != NULL && sys_stderr != Py_None) {
- PyFile_WriteObject(exc, sys_stderr, Py_PRINT_RAW);
- } else {
- PyObject_Print(exc, stderr, Py_PRINT_RAW);
- fflush(stderr);
+ if (PyObject_Print(exc, stderr, Py_PRINT_RAW) < 0) {
+ PyErr_Clear();
}
- Py_XDECREF(sys_stderr);
- PySys_WriteStderr("\n");
- exitcode = 1;
+ fflush(stderr);
}
-
-done:
+ PySys_WriteStderr("\n");
+ Py_XDECREF(sys_stderr);
Py_CLEAR(exc);
- *exitcode_p = exitcode;
+ *exitcode_p = 1;
return 1;
}
@@ -820,14 +722,11 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
PyErr_Clear();
goto done;
}
- _PyErr_WriteUnraisableMsg("in audit hook", NULL);
+ PyErr_FormatUnraisable("Exception ignored in audit hook");
}
if (hook) {
- PyObject* stack[3];
- stack[0] = typ;
- stack[1] = exc;
- stack[2] = tb;
- PyObject *result = _PyObject_FastCall(hook, stack, 3);
+ PyObject* args[3] = {typ, exc, tb};
+ PyObject *result = PyObject_Vectorcall(hook, args, 3, NULL);
if (result == NULL) {
handle_system_exit();
@@ -879,29 +778,13 @@ struct exception_print_context
{
PyObject *file;
PyObject *seen; // Prevent cycles in recursion
- int exception_group_depth; // nesting level of current exception group
- bool need_close; // Need a closing bottom frame
- int max_group_width; // Maximum number of children of each EG
- int max_group_depth; // Maximum nesting level of EGs
};
-#define EXC_MARGIN(ctx) ((ctx)->exception_group_depth ? "| " : "")
-#define EXC_INDENT(ctx) (2 * (ctx)->exception_group_depth)
-
-static int
-write_indented_margin(struct exception_print_context *ctx, PyObject *f)
-{
- return _Py_WriteIndentedMargin(EXC_INDENT(ctx), EXC_MARGIN(ctx), f);
-}
-
static int
print_exception_invalid_type(struct exception_print_context *ctx,
PyObject *value)
{
PyObject *f = ctx->file;
- if (_Py_WriteIndent(EXC_INDENT(ctx), f) < 0) {
- return -1;
- }
const char *const msg = "TypeError: print_exception(): Exception expected "
"for value, ";
if (PyFile_WriteString(msg, f) < 0) {
@@ -925,15 +808,7 @@ print_exception_traceback(struct exception_print_context *ctx, PyObject *value)
PyObject *tb = PyException_GetTraceback(value);
if (tb && tb != Py_None) {
const char *header = EXCEPTION_TB_HEADER;
- const char *header_margin = EXC_MARGIN(ctx);
- if (_PyBaseExceptionGroup_Check(value)) {
- header = EXCEPTION_GROUP_TB_HEADER;
- if (ctx->exception_group_depth == 1) {
- header_margin = "+ ";
- }
- }
- err = _PyTraceBack_Print_Indented(
- tb, EXC_INDENT(ctx), EXC_MARGIN(ctx), header_margin, header, f);
+ err = _PyTraceBack_Print(tb, header, f);
}
Py_XDECREF(tb);
return err;
@@ -946,7 +821,7 @@ print_exception_file_and_line(struct exception_print_context *ctx,
PyObject *f = ctx->file;
PyObject *tmp;
- int res = _PyObject_LookupAttr(*value_p, &_Py_ID(print_file_and_line), &tmp);
+ int res = PyObject_GetOptionalAttr(*value_p, &_Py_ID(print_file_and_line), &tmp);
if (res <= 0) {
if (res < 0) {
PyErr_Clear();
@@ -955,16 +830,20 @@ print_exception_file_and_line(struct exception_print_context *ctx,
}
Py_DECREF(tmp);
- PyObject *message, *filename, *text;
- Py_ssize_t lineno, offset, end_lineno, end_offset;
- if (!parse_syntax_error(*value_p, &message, &filename,
- &lineno, &offset,
- &end_lineno, &end_offset, &text)) {
- PyErr_Clear();
- return 0;
+ PyObject *filename = NULL;
+ Py_ssize_t lineno = 0;
+ PyObject* v = PyObject_GetAttr(*value_p, &_Py_ID(filename));
+ if (!v) {
+ return -1;
+ }
+ if (v == Py_None) {
+ Py_DECREF(v);
+ _Py_DECLARE_STR(anon_string, "<string>");
+ filename = Py_NewRef(&_Py_STR(anon_string));
+ }
+ else {
+ filename = v;
}
-
- Py_SETREF(*value_p, message);
PyObject *line = PyUnicode_FromFormat(" File \"%S\", line %zd\n",
filename, lineno);
@@ -972,40 +851,16 @@ print_exception_file_and_line(struct exception_print_context *ctx,
if (line == NULL) {
goto error;
}
- if (write_indented_margin(ctx, f) < 0) {
- goto error;
- }
if (PyFile_WriteObject(line, f, Py_PRINT_RAW) < 0) {
goto error;
}
Py_CLEAR(line);
- if (text != NULL) {
- Py_ssize_t line_size;
- const char *error_line = PyUnicode_AsUTF8AndSize(text, &line_size);
- // If the location of the error spawn multiple lines, we want
- // to just print the first one and highlight everything until
- // the end of that one since we don't support multi-line error
- // messages.
- if (end_lineno > lineno) {
- end_offset = (error_line != NULL) ? line_size : -1;
- }
- // Limit the amount of '^' that we can display to
- // the size of the text in the source line.
- if (error_line != NULL && end_offset > line_size + 1) {
- end_offset = line_size + 1;
- }
- if (print_error_text(f, offset, end_offset, text) < 0) {
- goto error;
- }
- Py_DECREF(text);
- }
assert(!PyErr_Occurred());
return 0;
error:
Py_XDECREF(line);
- Py_XDECREF(text);
return -1;
}
@@ -1016,11 +871,14 @@ print_exception_message(struct exception_print_context *ctx, PyObject *type,
{
PyObject *f = ctx->file;
- assert(PyExceptionClass_Check(type));
-
- if (write_indented_margin(ctx, f) < 0) {
+ if (PyErr_GivenExceptionMatches(value, PyExc_MemoryError)) {
+ // The Python APIs in this function require allocating memory
+ // for various objects. If we're out of memory, we can't do that,
return -1;
}
+
+ assert(PyExceptionClass_Check(type));
+
PyObject *modulename = PyObject_GetAttr(type, &_Py_ID(__module__));
if (modulename == NULL || !PyUnicode_Check(modulename)) {
Py_XDECREF(modulename);
@@ -1095,134 +953,8 @@ print_exception_message(struct exception_print_context *ctx, PyObject *type,
}
static int
-print_exception_suggestions(struct exception_print_context *ctx,
- PyObject *value)
-{
- PyObject *f = ctx->file;
- PyObject *suggestions = _Py_Offer_Suggestions(value);
- if (suggestions) {
- if (PyFile_WriteObject(suggestions, f, Py_PRINT_RAW) < 0) {
- goto error;
- }
- Py_DECREF(suggestions);
- }
- else if (PyErr_Occurred()) {
- PyErr_Clear();
- }
- return 0;
-error:
- Py_XDECREF(suggestions);
- return -1;
-}
-
-static int
-print_exception_notes(struct exception_print_context *ctx, PyObject *notes)
-{
- PyObject *f = ctx->file;
-
- if (notes == NULL) {
- return 0;
- }
-
- if (!PySequence_Check(notes) || PyUnicode_Check(notes) || PyBytes_Check(notes)) {
- int res = 0;
- if (write_indented_margin(ctx, f) < 0) {
- res = -1;
- }
- PyObject *s = PyObject_Repr(notes);
- if (s == NULL) {
- PyErr_Clear();
- res = PyFile_WriteString("<__notes__ repr() failed>", f);
- }
- else {
- res = PyFile_WriteObject(s, f, Py_PRINT_RAW);
- Py_DECREF(s);
- }
- if (PyFile_WriteString("\n", f) < 0) {
- res = -1;
- }
- return res;
- }
- Py_ssize_t num_notes = PySequence_Length(notes);
- PyObject *lines = NULL;
- for (Py_ssize_t ni = 0; ni < num_notes; ni++) {
- PyObject *note = PySequence_GetItem(notes, ni);
- PyObject *note_str = PyObject_Str(note);
- Py_DECREF(note);
-
- if (note_str == NULL) {
- PyErr_Clear();
- if (PyFile_WriteString("<note str() failed>", f) < 0) {
- goto error;
- }
- }
- else {
- lines = PyUnicode_Splitlines(note_str, 1);
- Py_DECREF(note_str);
-
- if (lines == NULL) {
- goto error;
- }
-
- Py_ssize_t n = PyList_GET_SIZE(lines);
- for (Py_ssize_t i = 0; i < n; i++) {
- PyObject *line = PyList_GET_ITEM(lines, i);
- assert(PyUnicode_Check(line));
- if (write_indented_margin(ctx, f) < 0) {
- goto error;
- }
- if (PyFile_WriteObject(line, f, Py_PRINT_RAW) < 0) {
- goto error;
- }
- }
- Py_CLEAR(lines);
- }
- if (PyFile_WriteString("\n", f) < 0) {
- goto error;
- }
- }
-
- return 0;
-error:
- Py_XDECREF(lines);
- return -1;
-}
-
-static int
-get_exception_notes(struct exception_print_context *ctx, PyObject *value, PyObject **notes) {
- PyObject *note = NULL;
-
- if (_PyObject_LookupAttr(value, &_Py_ID(__notes__), notes) < 0) {
- PyObject *type, *errvalue, *tback;
- PyErr_Fetch(&type, &errvalue, &tback);
- PyErr_NormalizeException(&type, &errvalue, &tback);
- note = PyUnicode_FromFormat("Ignored error getting __notes__: %R", errvalue);
- Py_XDECREF(type);
- Py_XDECREF(errvalue);
- Py_XDECREF(tback);
- if (!note) {
- goto error;
- }
- *notes = PyList_New(1);
- if (!*notes) {
- goto error;
- }
- if (PyList_SetItem(*notes, 0, note) < 0) {
- Py_DECREF(*notes);
- goto error;
- }
- }
-
- return 0;
-error:
- Py_XDECREF(note);
- return -1;
-}
-
-static int
print_exception(struct exception_print_context *ctx, PyObject *value)
{
- PyObject *notes = NULL;
PyObject *f = ctx->file;
if (!PyExceptionInstance_Check(value)) {
@@ -1238,9 +970,6 @@ print_exception(struct exception_print_context *ctx, PyObject *value)
/* grab the type and notes now because value can change below */
PyObject *type = (PyObject *) Py_TYPE(value);
- if (get_exception_notes(ctx, value, &notes) < 0) {
- goto error;
- }
if (print_exception_file_and_line(ctx, &value) < 0) {
goto error;
@@ -1248,22 +977,13 @@ print_exception(struct exception_print_context *ctx, PyObject *value)
if (print_exception_message(ctx, type, value) < 0) {
goto error;
}
- if (print_exception_suggestions(ctx, value) < 0) {
- goto error;
- }
if (PyFile_WriteString("\n", f) < 0) {
goto error;
}
- if (print_exception_notes(ctx, notes) < 0) {
- goto error;
- }
-
- Py_XDECREF(notes);
Py_DECREF(value);
assert(!PyErr_Occurred());
return 0;
error:
- Py_XDECREF(notes);
Py_DECREF(value);
return -1;
}
@@ -1287,29 +1007,18 @@ print_chained(struct exception_print_context* ctx, PyObject *value,
if (_Py_EnterRecursiveCall(" in print_chained")) {
return -1;
}
- bool need_close = ctx->need_close;
int res = print_exception_recursive(ctx, value);
- ctx->need_close = need_close;
_Py_LeaveRecursiveCall();
if (res < 0) {
return -1;
}
- if (write_indented_margin(ctx, f) < 0) {
- return -1;
- }
if (PyFile_WriteString("\n", f) < 0) {
return -1;
}
- if (write_indented_margin(ctx, f) < 0) {
- return -1;
- }
if (PyFile_WriteString(message, f) < 0) {
return -1;
}
- if (write_indented_margin(ctx, f) < 0) {
- return -1;
- }
if (PyFile_WriteString("\n", f) < 0) {
return -1;
}
@@ -1387,133 +1096,6 @@ print_exception_cause_and_context(struct exception_print_context *ctx,
}
static int
-print_exception_group(struct exception_print_context *ctx, PyObject *value)
-{
- PyObject *f = ctx->file;
-
- if (ctx->exception_group_depth > ctx->max_group_depth) {
- /* depth exceeds limit */
-
- if (write_indented_margin(ctx, f) < 0) {
- return -1;
- }
-
- PyObject *line = PyUnicode_FromFormat("... (max_group_depth is %d)\n",
- ctx->max_group_depth);
- if (line == NULL) {
- return -1;
- }
- int err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
- Py_DECREF(line);
- return err;
- }
-
- if (ctx->exception_group_depth == 0) {
- ctx->exception_group_depth += 1;
- }
- if (print_exception(ctx, value) < 0) {
- return -1;
- }
-
- PyObject *excs = ((PyBaseExceptionGroupObject *)value)->excs;
- assert(excs && PyTuple_Check(excs));
- Py_ssize_t num_excs = PyTuple_GET_SIZE(excs);
- assert(num_excs > 0);
- Py_ssize_t n;
- if (num_excs <= ctx->max_group_width) {
- n = num_excs;
- }
- else {
- n = ctx->max_group_width + 1;
- }
-
- ctx->need_close = false;
- for (Py_ssize_t i = 0; i < n; i++) {
- bool last_exc = (i == n - 1);
- if (last_exc) {
- // The closing frame may be added in a recursive call
- ctx->need_close = true;
- }
-
- if (_Py_WriteIndent(EXC_INDENT(ctx), f) < 0) {
- return -1;
- }
- bool truncated = (i >= ctx->max_group_width);
- PyObject *line;
- if (!truncated) {
- line = PyUnicode_FromFormat(
- "%s+---------------- %zd ----------------\n",
- (i == 0) ? "+-" : " ", i + 1);
- }
- else {
- line = PyUnicode_FromFormat(
- "%s+---------------- ... ----------------\n",
- (i == 0) ? "+-" : " ");
- }
- if (line == NULL) {
- return -1;
- }
- int err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
- Py_DECREF(line);
- if (err < 0) {
- return -1;
- }
-
- ctx->exception_group_depth += 1;
- PyObject *exc = PyTuple_GET_ITEM(excs, i);
-
- if (!truncated) {
- if (_Py_EnterRecursiveCall(" in print_exception_group")) {
- return -1;
- }
- int res = print_exception_recursive(ctx, exc);
- _Py_LeaveRecursiveCall();
- if (res < 0) {
- return -1;
- }
- }
- else {
- Py_ssize_t excs_remaining = num_excs - ctx->max_group_width;
-
- if (write_indented_margin(ctx, f) < 0) {
- return -1;
- }
-
- PyObject *line = PyUnicode_FromFormat(
- "and %zd more exception%s\n",
- excs_remaining, excs_remaining > 1 ? "s" : "");
-
- if (line == NULL) {
- return -1;
- }
-
- int err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
- Py_DECREF(line);
- if (err < 0) {
- return -1;
- }
- }
-
- if (last_exc && ctx->need_close) {
- if (_Py_WriteIndent(EXC_INDENT(ctx), f) < 0) {
- return -1;
- }
- if (PyFile_WriteString(
- "+------------------------------------\n", f) < 0) {
- return -1;
- }
- ctx->need_close = false;
- }
- ctx->exception_group_depth -= 1;
- }
-
- if (ctx->exception_group_depth == 1) {
- ctx->exception_group_depth -= 1;
- }
- return 0;
-}
-
-static int
print_exception_recursive(struct exception_print_context *ctx, PyObject *value)
{
if (_Py_EnterRecursiveCall(" in print_exception_recursive")) {
@@ -1525,12 +1107,7 @@ print_exception_recursive(struct exception_print_context *ctx, PyObject *value)
goto error;
}
}
- if (!_PyBaseExceptionGroup_Check(value)) {
- if (print_exception(ctx, value) < 0) {
- goto error;
- }
- }
- else if (print_exception_group(ctx, value) < 0) {
+ if (print_exception(ctx, value) < 0) {
goto error;
}
assert(!PyErr_Occurred());
@@ -1542,12 +1119,10 @@ error:
return -1;
}
-#define PyErr_MAX_GROUP_WIDTH 15
-#define PyErr_MAX_GROUP_DEPTH 10
-
void
_PyErr_Display(PyObject *file, PyObject *unused, PyObject *value, PyObject *tb)
{
+ assert(value != NULL);
assert(file != NULL && file != Py_None);
if (PyExceptionInstance_Check(value)
&& tb != NULL && PyTraceBack_Check(tb)) {
@@ -1562,12 +1137,42 @@ _PyErr_Display(PyObject *file, PyObject *unused, PyObject *value, PyObject *tb)
}
}
+ int unhandled_keyboard_interrupt = _PyRuntime.signals.unhandled_keyboard_interrupt;
+
+ // Try first with the stdlib traceback module
+ PyObject *traceback_module = PyImport_ImportModule("traceback");
+
+ if (traceback_module == NULL) {
+ goto fallback;
+ }
+
+ PyObject *print_exception_fn = PyObject_GetAttrString(traceback_module, "_print_exception_bltin");
+
+ if (print_exception_fn == NULL || !PyCallable_Check(print_exception_fn)) {
+ Py_DECREF(traceback_module);
+ goto fallback;
+ }
+
+ PyObject* result = PyObject_CallOneArg(print_exception_fn, value);
+
+ Py_DECREF(traceback_module);
+ Py_XDECREF(print_exception_fn);
+ if (result) {
+ Py_DECREF(result);
+ _PyRuntime.signals.unhandled_keyboard_interrupt = unhandled_keyboard_interrupt;
+ return;
+ }
+fallback:
+ _PyRuntime.signals.unhandled_keyboard_interrupt = unhandled_keyboard_interrupt;
+#ifdef Py_DEBUG
+ if (PyErr_Occurred()) {
+ PyErr_FormatUnraisable(
+ "Exception ignored in the internal traceback machinery");
+ }
+#endif
+ PyErr_Clear();
struct exception_print_context ctx;
ctx.file = file;
- ctx.exception_group_depth = 0;
- ctx.need_close = false;
- ctx.max_group_width = PyErr_MAX_GROUP_WIDTH;
- ctx.max_group_depth = PyErr_MAX_GROUP_DEPTH;
/* We choose to ignore seen being possibly NULL, and report
at least the main exception (it could be a MemoryError).
@@ -1584,14 +1189,10 @@ _PyErr_Display(PyObject *file, PyObject *unused, PyObject *value, PyObject *tb)
Py_XDECREF(ctx.seen);
/* Call file.flush() */
- PyObject *res = _PyObject_CallMethodNoArgs(file, &_Py_ID(flush));
- if (!res) {
+ if (_PyFile_Flush(file) < 0) {
/* Silently ignore file.flush() error */
PyErr_Clear();
}
- else {
- Py_DECREF(res);
- }
}
void
@@ -1629,9 +1230,10 @@ void PyErr_DisplayException(PyObject *exc)
PyErr_Display(NULL, exc, NULL);
}
-PyObject *
-PyRun_StringFlags(const char *str, int start, PyObject *globals,
- PyObject *locals, PyCompilerFlags *flags)
+static PyObject *
+_PyRun_StringFlagsWithName(const char *str, PyObject* name, int start,
+ PyObject *globals, PyObject *locals, PyCompilerFlags *flags,
+ int generate_new_source)
{
PyObject *ret = NULL;
mod_ty mod;
@@ -1641,17 +1243,36 @@ PyRun_StringFlags(const char *str, int start, PyObject *globals,
if (arena == NULL)
return NULL;
+ PyObject* source = NULL;
_Py_DECLARE_STR(anon_string, "<string>");
- mod = _PyParser_ASTFromString(
- str, &_Py_STR(anon_string), start, flags, arena);
- if (mod != NULL)
- ret = run_mod(mod, &_Py_STR(anon_string), globals, locals, flags, arena);
+ if (name) {
+ source = PyUnicode_FromString(str);
+ if (!source) {
+ PyErr_Clear();
+ }
+ } else {
+ name = &_Py_STR(anon_string);
+ }
+
+ mod = _PyParser_ASTFromString(str, name, start, flags, arena);
+
+ if (mod != NULL) {
+ ret = run_mod(mod, name, globals, locals, flags, arena, source, generate_new_source);
+ }
+ Py_XDECREF(source);
_PyArena_Free(arena);
return ret;
}
+PyObject *
+PyRun_StringFlags(const char *str, int start, PyObject *globals,
+ PyObject *locals, PyCompilerFlags *flags) {
+
+ return _PyRun_StringFlagsWithName(str, NULL, start, globals, locals, flags, 0);
+}
+
static PyObject *
pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals,
PyObject *locals, int closeit, PyCompilerFlags *flags)
@@ -1671,7 +1292,7 @@ pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals,
PyObject *ret;
if (mod != NULL) {
- ret = run_mod(mod, filename, globals, locals, flags, arena);
+ ret = run_mod(mod, filename, globals, locals, flags, arena, NULL, 0);
}
else {
ret = NULL;
@@ -1706,11 +1327,7 @@ flush_io_stream(PyThreadState *tstate, PyObject *name)
PyErr_Clear();
}
if (f != NULL) {
- PyObject *r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush));
- if (r) {
- Py_DECREF(r);
- }
- else {
+ if (_PyFile_Flush(f) < 0) {
PyErr_Clear();
}
Py_DECREF(f);
@@ -1745,9 +1362,16 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py
_PyRuntime.signals.unhandled_keyboard_interrupt = 0;
/* Set globals['__builtins__'] if it doesn't exist */
- if (globals != NULL && _PyDict_GetItemStringWithError(globals, "__builtins__") == NULL) {
- if (PyErr_Occurred() ||
- PyDict_SetItemString(globals, "__builtins__",
+ if (!globals || !PyDict_Check(globals)) {
+ PyErr_SetString(PyExc_SystemError, "globals must be a real dict");
+ return NULL;
+ }
+ int has_builtins = PyDict_ContainsString(globals, "__builtins__");
+ if (has_builtins < 0) {
+ return NULL;
+ }
+ if (!has_builtins) {
+ if (PyDict_SetItemString(globals, "__builtins__",
tstate->interp->builtins) < 0)
{
return NULL;
@@ -1762,13 +1386,100 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py
}
static PyObject *
+get_interactive_filename(PyObject *filename, Py_ssize_t count)
+{
+ PyObject *result;
+ Py_ssize_t len = PyUnicode_GET_LENGTH(filename);
+
+ if (len >= 2
+ && PyUnicode_ReadChar(filename, 0) == '<'
+ && PyUnicode_ReadChar(filename, len - 1) == '>') {
+ PyObject *middle = PyUnicode_Substring(filename, 1, len-1);
+ if (middle == NULL) {
+ return NULL;
+ }
+ result = PyUnicode_FromFormat("<%U-%d>", middle, count);
+ Py_DECREF(middle);
+ } else {
+ result = PyUnicode_FromFormat(
+ "%U-%d", filename, count);
+ }
+ return result;
+
+}
+
+static PyObject *
run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals,
- PyCompilerFlags *flags, PyArena *arena)
+ PyCompilerFlags *flags, PyArena *arena, PyObject* interactive_src,
+ int generate_new_source)
{
PyThreadState *tstate = _PyThreadState_GET();
- PyCodeObject *co = _PyAST_Compile(mod, filename, flags, -1, arena);
- if (co == NULL)
+ PyObject* interactive_filename = filename;
+ if (interactive_src) {
+ PyInterpreterState *interp = tstate->interp;
+ if (generate_new_source) {
+ interactive_filename = get_interactive_filename(
+ filename, interp->_interactive_src_count++);
+ } else {
+ Py_INCREF(interactive_filename);
+ }
+ if (interactive_filename == NULL) {
+ return NULL;
+ }
+ }
+
+ PyCodeObject *co = _PyAST_Compile(mod, interactive_filename, flags, -1, arena);
+ if (co == NULL) {
+ if (interactive_src) {
+ Py_DECREF(interactive_filename);
+ }
return NULL;
+ }
+
+ if (interactive_src) {
+ PyObject *linecache_module = PyImport_ImportModule("linecache");
+
+ if (linecache_module == NULL) {
+ Py_DECREF(co);
+ Py_DECREF(interactive_filename);
+ return NULL;
+ }
+
+ PyObject *print_tb_func = PyObject_GetAttrString(linecache_module, "_register_code");
+
+ if (print_tb_func == NULL) {
+ Py_DECREF(co);
+ Py_DECREF(interactive_filename);
+ Py_DECREF(linecache_module);
+ return NULL;
+ }
+
+ if (!PyCallable_Check(print_tb_func)) {
+ Py_DECREF(co);
+ Py_DECREF(interactive_filename);
+ Py_DECREF(linecache_module);
+ Py_DECREF(print_tb_func);
+ PyErr_SetString(PyExc_ValueError, "linecache._register_code is not callable");
+ return NULL;
+ }
+
+ PyObject* result = PyObject_CallFunction(
+ print_tb_func, "OOO",
+ co,
+ interactive_src,
+ filename
+ );
+
+ Py_DECREF(interactive_filename);
+
+ Py_DECREF(linecache_module);
+ Py_XDECREF(print_tb_func);
+ Py_XDECREF(result);
+ if (!result) {
+ Py_DECREF(co);
+ return NULL;
+ }
+ }
if (_PySys_Audit(tstate, "exec", "O", co) < 0) {
Py_DECREF(co);
@@ -1839,6 +1550,12 @@ Py_CompileStringObject(const char *str, PyObject *filename, int start,
return NULL;
}
if (flags && (flags->cf_flags & PyCF_ONLY_AST)) {
+ if ((flags->cf_flags & PyCF_OPTIMIZED_AST) == PyCF_OPTIMIZED_AST) {
+ if (_PyCompile_AstOptimize(mod, filename, flags, optimize, arena) < 0) {
+ _PyArena_Free(arena);
+ return NULL;
+ }
+ }
PyObject *result = PyAST_mod2obj(mod);
_PyArena_Free(arena);
return result;
@@ -2049,7 +1766,3 @@ PyRun_InteractiveLoop(FILE *f, const char *p)
{
return PyRun_InteractiveLoopFlags(f, p, NULL);
}
-
-#ifdef __cplusplus
-}
-#endif