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
56 lines
1.7 KiB
C
56 lines
1.7 KiB
C
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup pythonintern
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#if PY_VERSION_HEX < 0x030a0000
|
|
# error "Python 3.10 or greater is required, you'll need to update your Python."
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
struct ReportList;
|
|
|
|
/** Error reporting: convert BKE_report (#ReportList) reports into python errors.
|
|
*
|
|
* \param clear: When `true`, #BKE_reports_free is called on the given `reports`, which should
|
|
* then be considered as 'freed' data and not used anymore. */
|
|
short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, bool clear);
|
|
/**
|
|
* A version of #BKE_report_write_file_fp that uses Python's stdout.
|
|
*/
|
|
void BPy_reports_write_stdout(const struct ReportList *reports, const char *header);
|
|
bool BPy_errors_to_report_ex(struct ReportList *reports,
|
|
const char *error_prefix,
|
|
bool use_full,
|
|
bool use_location);
|
|
/**
|
|
* \param reports: Any errors will be added to the report list.
|
|
*
|
|
* \note The reports are never printed to the `stdout/stderr`,
|
|
* so you may wish to call either `BKE_reports_print(reports)` or `PyErr_Print()` afterwards.
|
|
* Typically `PyErr_Print()` is preferable as `sys.excepthook` is called.
|
|
*
|
|
* \note The caller is responsible for clearing the error (see #PyErr_Clear).
|
|
*/
|
|
bool BPy_errors_to_report(struct ReportList *reports);
|
|
|
|
struct bContext *BPY_context_get(void);
|
|
|
|
extern void bpy_context_set(struct bContext *C, PyGILState_STATE *gilstate);
|
|
/**
|
|
* Context should be used but not now because it causes some bugs.
|
|
*/
|
|
extern void bpy_context_clear(struct bContext *C, const PyGILState_STATE *gilstate);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|