aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Python/pythonrun.c
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.com>2024-02-12 07:53:52 +0300
committerDaniil Cherednik <dcherednik@ydb.tech>2024-02-14 14:26:16 +0000
commit31f2a419764a8ba77c2a970cfc80056c6cd06756 (patch)
treec1995d239eba8571cefc640f6648e1d5dd4ce9e2 /contrib/tools/python3/src/Python/pythonrun.c
parentfe2ef02b38d9c85d80060963b265a1df9f38c3bb (diff)
downloadydb-31f2a419764a8ba77c2a970cfc80056c6cd06756.tar.gz
Update Python from 3.11.8 to 3.12.2
Diffstat (limited to 'contrib/tools/python3/src/Python/pythonrun.c')
-rw-r--r--contrib/tools/python3/src/Python/pythonrun.c235
1 files changed, 108 insertions, 127 deletions
diff --git a/contrib/tools/python3/src/Python/pythonrun.c b/contrib/tools/python3/src/Python/pythonrun.c
index fca8b7ab66..5f3d249df4 100644
--- a/contrib/tools/python3/src/Python/pythonrun.c
+++ b/contrib/tools/python3/src/Python/pythonrun.c
@@ -18,13 +18,12 @@
#include "pycore_interp.h" // PyInterpreterState.importlib
#include "pycore_object.h" // _PyDebug_PrintTotalRefs()
#include "pycore_parser.h" // _PyParser_ASTFromString()
-#include "pycore_pyerrors.h" // _PyErr_Fetch, _Py_Offer_Suggestions
+#include "pycore_pyerrors.h" // _PyErr_GetRaisedException, _Py_Offer_Suggestions
#include "pycore_pylifecycle.h" // _Py_UnhandledKeyboardInterrupt
#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_sysmodule.h" // _PySys_Audit()
#include "pycore_traceback.h" // _PyTraceBack_Print_Indented()
-#include "token.h" // INDENT
#include "errcode.h" // E_EOF
#include "marshal.h" // PyMarshal_ReadLongFromFile()
@@ -351,14 +350,8 @@ static int
set_main_loader(PyObject *d, PyObject *filename, const char *loader_name)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
- PyObject *bootstrap = PyObject_GetAttrString(interp->importlib,
- "_bootstrap_external");
- if (bootstrap == NULL) {
- return -1;
- }
-
- PyObject *loader_type = PyObject_GetAttrString(bootstrap, loader_name);
- Py_DECREF(bootstrap);
+ PyObject *loader_type = _PyImport_GetImportlibExternalLoader(interp,
+ loader_name);
if (loader_type == NULL) {
return -1;
}
@@ -516,8 +509,7 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename,
if (v == Py_None) {
Py_DECREF(v);
_Py_DECLARE_STR(anon_string, "<string>");
- *filename = &_Py_STR(anon_string);
- Py_INCREF(*filename);
+ *filename = Py_NewRef(&_Py_STR(anon_string));
}
else {
*filename = v;
@@ -706,31 +698,30 @@ _Py_HandleSystemExit(int *exitcode_p)
return 0;
}
- PyObject *exception, *value, *tb;
- PyErr_Fetch(&exception, &value, &tb);
-
fflush(stdout);
int exitcode = 0;
- if (value == NULL || value == Py_None) {
+
+ PyObject *exc = PyErr_GetRaisedException();
+ if (exc == NULL) {
goto done;
}
+ assert(PyExceptionInstance_Check(exc));
- if (PyExceptionInstance_Check(value)) {
- /* The error code should be in the `code' attribute. */
- PyObject *code = PyObject_GetAttr(value, &_Py_ID(code));
- if (code) {
- Py_DECREF(value);
- value = code;
- if (value == Py_None)
- goto done;
+ /* The error code should be in the `code' attribute. */
+ PyObject *code = PyObject_GetAttr(exc, &_Py_ID(code));
+ if (code) {
+ 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 we failed to dig out the 'code' attribute,
+ * just let the else clause below print the error.
+ */
- if (PyLong_Check(value)) {
- exitcode = (int)PyLong_AsLong(value);
+ if (PyLong_Check(exc)) {
+ exitcode = (int)PyLong_AsLong(exc);
}
else {
PyThreadState *tstate = _PyThreadState_GET();
@@ -741,23 +732,17 @@ _Py_HandleSystemExit(int *exitcode_p)
*/
PyErr_Clear();
if (sys_stderr != NULL && sys_stderr != Py_None) {
- PyFile_WriteObject(value, sys_stderr, Py_PRINT_RAW);
+ PyFile_WriteObject(exc, sys_stderr, Py_PRINT_RAW);
} else {
- PyObject_Print(value, stderr, Py_PRINT_RAW);
+ PyObject_Print(exc, stderr, Py_PRINT_RAW);
fflush(stderr);
}
PySys_WriteStderr("\n");
exitcode = 1;
}
- done:
- /* Restore and clear the exception info, in order to properly decref
- * the exception, value, and traceback. If we just exit instead,
- * these leak, which confuses PYTHONDUMPREFS output, and may prevent
- * some finalizers from running.
- */
- PyErr_Restore(exception, value, tb);
- PyErr_Clear();
+done:
+ Py_CLEAR(exc);
*exitcode_p = exitcode;
return 1;
}
@@ -776,40 +761,38 @@ handle_system_exit(void)
static void
_PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
{
- PyObject *exception, *v, *tb, *hook;
-
+ PyObject *typ = NULL, *tb = NULL;
handle_system_exit();
- _PyErr_Fetch(tstate, &exception, &v, &tb);
- if (exception == NULL) {
+ PyObject *exc = _PyErr_GetRaisedException(tstate);
+ if (exc == NULL) {
goto done;
}
-
- _PyErr_NormalizeException(tstate, &exception, &v, &tb);
+ assert(PyExceptionInstance_Check(exc));
+ typ = Py_NewRef(Py_TYPE(exc));
+ tb = PyException_GetTraceback(exc);
if (tb == NULL) {
- tb = Py_None;
- Py_INCREF(tb);
- }
- PyException_SetTraceback(v, tb);
- if (exception == NULL) {
- goto done;
+ tb = Py_NewRef(Py_None);
}
- /* Now we know v != NULL too */
if (set_sys_last_vars) {
- if (_PySys_SetAttr(&_Py_ID(last_type), exception) < 0) {
+ if (_PySys_SetAttr(&_Py_ID(last_exc), exc) < 0) {
_PyErr_Clear(tstate);
}
- if (_PySys_SetAttr(&_Py_ID(last_value), v) < 0) {
+ /* Legacy version: */
+ if (_PySys_SetAttr(&_Py_ID(last_type), typ) < 0) {
+ _PyErr_Clear(tstate);
+ }
+ if (_PySys_SetAttr(&_Py_ID(last_value), exc) < 0) {
_PyErr_Clear(tstate);
}
if (_PySys_SetAttr(&_Py_ID(last_traceback), tb) < 0) {
_PyErr_Clear(tstate);
}
}
- hook = _PySys_GetAttr(tstate, &_Py_ID(excepthook));
+ PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(excepthook));
if (_PySys_Audit(tstate, "sys.excepthook", "OOOO", hook ? hook : Py_None,
- exception, v, tb) < 0) {
+ typ, exc, tb) < 0) {
if (PyErr_ExceptionMatches(PyExc_RuntimeError)) {
PyErr_Clear();
goto done;
@@ -818,48 +801,34 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
}
if (hook) {
PyObject* stack[3];
- PyObject *result;
-
- stack[0] = exception;
- stack[1] = v;
+ stack[0] = typ;
+ stack[1] = exc;
stack[2] = tb;
- result = _PyObject_FastCall(hook, stack, 3);
+ PyObject *result = _PyObject_FastCall(hook, stack, 3);
if (result == NULL) {
handle_system_exit();
- PyObject *exception2, *v2, *tb2;
- _PyErr_Fetch(tstate, &exception2, &v2, &tb2);
- _PyErr_NormalizeException(tstate, &exception2, &v2, &tb2);
- /* It should not be possible for exception2 or v2
- to be NULL. However PyErr_Display() can't
- tolerate NULLs, so just be safe. */
- if (exception2 == NULL) {
- exception2 = Py_None;
- Py_INCREF(exception2);
- }
- if (v2 == NULL) {
- v2 = Py_None;
- Py_INCREF(v2);
- }
+ PyObject *exc2 = _PyErr_GetRaisedException(tstate);
+ assert(exc2 && PyExceptionInstance_Check(exc2));
fflush(stdout);
PySys_WriteStderr("Error in sys.excepthook:\n");
- PyErr_Display(exception2, v2, tb2);
+ PyErr_DisplayException(exc2);
PySys_WriteStderr("\nOriginal exception was:\n");
- PyErr_Display(exception, v, tb);
- Py_DECREF(exception2);
- Py_DECREF(v2);
- Py_XDECREF(tb2);
+ PyErr_DisplayException(exc);
+ Py_DECREF(exc2);
+ }
+ else {
+ Py_DECREF(result);
}
- Py_XDECREF(result);
}
else {
PySys_WriteStderr("sys.excepthook is missing\n");
- PyErr_Display(exception, v, tb);
+ PyErr_DisplayException(exc);
}
done:
- Py_XDECREF(exception);
- Py_XDECREF(v);
+ Py_XDECREF(typ);
+ Py_XDECREF(exc);
Py_XDECREF(tb);
}
@@ -1108,16 +1077,9 @@ print_exception_suggestions(struct exception_print_context *ctx,
PyObject *f = ctx->file;
PyObject *suggestions = _Py_Offer_Suggestions(value);
if (suggestions) {
- // Add a trailer ". Did you mean: (...)?"
- if (PyFile_WriteString(". Did you mean: '", f) < 0) {
- goto error;
- }
if (PyFile_WriteObject(suggestions, f, Py_PRINT_RAW) < 0) {
goto error;
}
- if (PyFile_WriteString("'?", f) < 0) {
- goto error;
- }
Py_DECREF(suggestions);
}
else if (PyErr_Occurred()) {
@@ -1138,7 +1100,7 @@ print_exception_notes(struct exception_print_context *ctx, PyObject *notes)
return 0;
}
- if (!PySequence_Check(notes)) {
+ if (!PySequence_Check(notes) || PyUnicode_Check(notes) || PyBytes_Check(notes)) {
int res = 0;
if (write_indented_margin(ctx, f) < 0) {
res = -1;
@@ -1152,6 +1114,9 @@ print_exception_notes(struct exception_print_context *ctx, PyObject *notes)
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);
@@ -1295,8 +1260,7 @@ print_chained(struct exception_print_context* ctx, PyObject *value,
const char * message, const char *tag)
{
PyObject *f = ctx->file;
-
- if (_Py_EnterRecursiveCall(" in print_chained") < 0) {
+ if (_Py_EnterRecursiveCall(" in print_chained")) {
return -1;
}
bool need_close = ctx->need_close;
@@ -1423,7 +1387,9 @@ print_exception_group(struct exception_print_context *ctx, PyObject *value)
if (ctx->exception_group_depth == 0) {
ctx->exception_group_depth += 1;
}
- print_exception(ctx, value);
+ if (print_exception(ctx, value) < 0) {
+ return -1;
+ }
PyObject *excs = ((PyBaseExceptionGroupObject *)value)->excs;
assert(excs && PyTuple_Check(excs));
@@ -1473,7 +1439,7 @@ print_exception_group(struct exception_print_context *ctx, PyObject *value)
PyObject *exc = PyTuple_GET_ITEM(excs, i);
if (!truncated) {
- if (_Py_EnterRecursiveCall(" in print_exception_group") != 0) {
+ if (_Py_EnterRecursiveCall(" in print_exception_group")) {
return -1;
}
int res = print_exception_recursive(ctx, exc);
@@ -1526,29 +1492,37 @@ print_exception_group(struct exception_print_context *ctx, PyObject *value)
static int
print_exception_recursive(struct exception_print_context *ctx, PyObject *value)
{
+ if (_Py_EnterRecursiveCall(" in print_exception_recursive")) {
+ return -1;
+ }
if (ctx->seen != NULL) {
/* Exception chaining */
if (print_exception_cause_and_context(ctx, value) < 0) {
- return -1;
+ goto error;
}
}
if (!_PyBaseExceptionGroup_Check(value)) {
if (print_exception(ctx, value) < 0) {
- return -1;
+ goto error;
}
}
else if (print_exception_group(ctx, value) < 0) {
- return -1;
+ goto error;
}
assert(!PyErr_Occurred());
+
+ _Py_LeaveRecursiveCall();
return 0;
+error:
+ _Py_LeaveRecursiveCall();
+ return -1;
}
#define PyErr_MAX_GROUP_WIDTH 15
#define PyErr_MAX_GROUP_DEPTH 10
void
-_PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *tb)
+_PyErr_Display(PyObject *file, PyObject *unused, PyObject *value, PyObject *tb)
{
assert(file != NULL && file != Py_None);
if (PyExceptionInstance_Check(value)
@@ -1556,10 +1530,12 @@ _PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *t
/* Put the traceback on the exception, otherwise it won't get
displayed. See issue #18776. */
PyObject *cur_tb = PyException_GetTraceback(value);
- if (cur_tb == NULL)
+ if (cur_tb == NULL) {
PyException_SetTraceback(value, tb);
- else
+ }
+ else {
Py_DECREF(cur_tb);
+ }
}
struct exception_print_context ctx;
@@ -1595,7 +1571,7 @@ _PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *t
}
void
-PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
+PyErr_Display(PyObject *unused, PyObject *value, PyObject *tb)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *file = _PySys_GetAttr(tstate, &_Py_ID(stderr));
@@ -1608,10 +1584,20 @@ PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
return;
}
Py_INCREF(file);
- _PyErr_Display(file, exception, value, tb);
+ _PyErr_Display(file, NULL, value, tb);
Py_DECREF(file);
}
+void _PyErr_DisplayException(PyObject *file, PyObject *exc)
+{
+ _PyErr_Display(file, NULL, exc, NULL);
+}
+
+void PyErr_DisplayException(PyObject *exc)
+{
+ PyErr_Display(NULL, exc, NULL);
+}
+
PyObject *
PyRun_StringFlags(const char *str, int start, PyObject *globals,
PyObject *locals, PyCompilerFlags *flags)
@@ -1681,35 +1667,29 @@ PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,
}
-
static void
-flush_io(void)
+flush_io_stream(PyThreadState *tstate, PyObject *name)
{
- PyObject *f, *r;
- PyObject *type, *value, *traceback;
-
- /* Save the current exception */
- PyErr_Fetch(&type, &value, &traceback);
-
- PyThreadState *tstate = _PyThreadState_GET();
- f = _PySys_GetAttr(tstate, &_Py_ID(stderr));
- if (f != NULL) {
- r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush));
- if (r)
- Py_DECREF(r);
- else
- PyErr_Clear();
- }
- f = _PySys_GetAttr(tstate, &_Py_ID(stdout));
+ PyObject *f = _PySys_GetAttr(tstate, name);
if (f != NULL) {
- r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush));
- if (r)
+ PyObject *r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush));
+ if (r) {
Py_DECREF(r);
- else
+ }
+ else {
PyErr_Clear();
+ }
}
+}
- PyErr_Restore(type, value, traceback);
+static void
+flush_io(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *exc = _PyErr_GetRaisedException(tstate);
+ flush_io_stream(tstate, &_Py_ID(stderr));
+ flush_io_stream(tstate, &_Py_ID(stdout));
+ _PyErr_SetRaisedException(tstate, exc);
}
static PyObject *
@@ -1726,7 +1706,8 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py
* uncaught exception to trigger an unexplained signal exit from a future
* Py_Main() based one.
*/
- _Py_UnhandledKeyboardInterrupt = 0;
+ // XXX Isn't this dealt with by the move to _PyRuntimeState?
+ _PyRuntime.signals.unhandled_keyboard_interrupt = 0;
/* Set globals['__builtins__'] if it doesn't exist */
if (globals != NULL && _PyDict_GetItemStringWithError(globals, "__builtins__") == NULL) {
@@ -1740,7 +1721,7 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py
v = PyEval_EvalCode((PyObject*)co, globals, locals);
if (!v && _PyErr_Occurred(tstate) == PyExc_KeyboardInterrupt) {
- _Py_UnhandledKeyboardInterrupt = 1;
+ _PyRuntime.signals.unhandled_keyboard_interrupt = 1;
}
return v;
}