Python: flush stdout and stderr after running Python script
When debugging with gdb in vscode, the stuff I print when executing a script in the text editor does not show up in the terminal. It does work when I flush explicitly though using `print(..., flush=True)`. This is quite annoying. The solution is to always flush `stdout` and `stderr` automatically when running a script. This is done using the CPython API, as just using `fflush(stdout/stderr)` did not solve the issue. Pull Request: https://projects.blender.org/blender/blender/pulls/136632
This commit is contained in:
@@ -1687,6 +1687,46 @@ bool PyC_RunString_AsStringOrNone(const char *imports[],
|
||||
|
||||
#endif /* #ifndef MATH_STANDALONE */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Std Files Flush
|
||||
*
|
||||
* \{ */
|
||||
|
||||
void PyC_StdFilesFlush()
|
||||
{
|
||||
/* This is ported from CPython's internal #flush_std_files (2025-03-31). The code is a bit
|
||||
* different because the original code uses some internal APIs.
|
||||
*
|
||||
* This is approximately equivalent to:
|
||||
* ```
|
||||
* try:
|
||||
* sys.stdout.flush()
|
||||
* sys.stderr.flush()
|
||||
* except Exception:
|
||||
* pass
|
||||
* ```
|
||||
*/
|
||||
PyObject *py_flush = PyUnicode_FromString("flush");
|
||||
BLI_assert(py_flush);
|
||||
for (const char *name : {"stdout", "stderr"}) {
|
||||
PyObject *py_file = PySys_GetObject(name);
|
||||
if (!py_file) {
|
||||
PyErr_Clear();
|
||||
continue;
|
||||
}
|
||||
PyObject *py_flush_retval = PyObject_CallMethodNoArgs(py_file, py_flush);
|
||||
if (py_flush_retval) {
|
||||
Py_DECREF(py_flush_retval);
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
Py_DECREF(py_flush);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Int Conversion
|
||||
*
|
||||
|
||||
@@ -259,6 +259,11 @@ bool PyC_RunString_AsStringOrNone(const char **imports,
|
||||
const char *filename,
|
||||
char **r_value) ATTR_NONNULL(2, 3, 4) ATTR_WARN_UNUSED_RESULT;
|
||||
|
||||
/**
|
||||
* Flush stdout and stderr. Errors are ignored.
|
||||
*/
|
||||
void PyC_StdFilesFlush();
|
||||
|
||||
/**
|
||||
* Use with PyArg_ParseTuple's "O&" formatting.
|
||||
*
|
||||
|
||||
@@ -217,6 +217,10 @@ static bool python_script_exec(
|
||||
|
||||
PyC_MainModule_Restore(main_mod);
|
||||
|
||||
/* Flush stdout/stderr to ensure the script output is visible.
|
||||
* Using fflush(stdout) does not solve it. */
|
||||
PyC_StdFilesFlush();
|
||||
|
||||
bpy_context_clear(C, &gilstate);
|
||||
|
||||
return (py_result != nullptr);
|
||||
|
||||
Reference in New Issue
Block a user