PyAPI: call 'sys.excepthook' for text editor exceptions

Resolves #115090, where exceptions from the text editor called
`sys.excepthook` in v3.6 but not in v4.0.

The error was caused by PyC_ExceptionBuffer calling PyErr_Display
instead of PyErr_Print.

While technically a regression in [0], the behavior in 3.6x wasn't
working properly either since a user-defined `sys.excepthook` could
prevent PyC_ExceptionBuffer from accessing the exception text.

Resolve with the following changes:

- BPy_errors_to_report has been updated not to print errors.
  Previously BPy_errors_to_report would *sometimes* print the error,
  which complicated situations where the caller wanted predictable
  behavior (always printing or never printing).

- `PyErr_Print()` must be used to display errors to the output,
  this will call `sys.excepthook` as it used to.

It's better not to rely on side effects of BPy_errors_to_report()
for error handling.

[0]: 6a0f98aeef
This commit is contained in:
Campbell Barton
2023-11-28 11:26:28 +11:00
parent 1e84a028b3
commit 2e1486da60
5 changed files with 28 additions and 27 deletions

View File

@@ -180,7 +180,9 @@ static bool python_script_exec(
}
if (!py_result) {
BPy_errors_to_report(reports);
if (reports) {
BPy_errors_to_report(reports);
}
if (text) {
if (do_jump) {
/* ensure text is valid before use, the script may have freed itself */
@@ -190,6 +192,7 @@ static bool python_script_exec(
}
}
}
PyErr_Print();
PyErr_Clear();
}
else {
@@ -272,12 +275,9 @@ static bool bpy_run_string_impl(bContext *C,
ReportList reports;
BKE_reports_init(&reports, RPT_STORE);
BPy_errors_to_report(&reports);
PyErr_Clear();
/* Ensure the reports are printed. */
if (!BKE_reports_print_test(&reports, RPT_ERROR)) {
BKE_reports_print(&reports, RPT_ERROR);
}
PyErr_Print();
PyErr_Clear();
ReportList *wm_reports = CTX_wm_reports(C);
if (wm_reports) {