PyAPI: free internal Python data using sys.exit(..)
Previously BPY_python_end wasn't called when scripts called sys.exit() because BPY_python_end exited the Python interpreter. Change this behavior to call BPY_python_end without exiting the Python interpreter while freeing Blender/Python data. While leaks in the context of sys.exit aren't especially important it's generally preferable for sys.exit() to match Blender's code-paths for exiting to avoid unexpected behavior.
This commit is contained in:
@@ -23,7 +23,7 @@ extern "C" {
|
||||
|
||||
/** Call #BPY_context_set first. */
|
||||
void BPY_python_start(struct bContext *C, int argc, const char **argv);
|
||||
void BPY_python_end(void);
|
||||
void BPY_python_end(bool do_python_exit);
|
||||
void BPY_python_reset(struct bContext *C);
|
||||
void BPY_python_use_system_env(void);
|
||||
void BPY_python_backtrace(FILE *fp);
|
||||
|
||||
@@ -535,7 +535,7 @@ void BPY_python_start(bContext *C, int argc, const char **argv)
|
||||
#endif
|
||||
}
|
||||
|
||||
void BPY_python_end()
|
||||
void BPY_python_end(const bool do_python_exit)
|
||||
{
|
||||
PyGILState_STATE gilstate;
|
||||
|
||||
@@ -564,14 +564,16 @@ void BPY_python_end()
|
||||
BPY_app_translations_end();
|
||||
|
||||
#ifndef WITH_PYTHON_MODULE
|
||||
/* Without this we get recursive calls to #WM_exit. */
|
||||
/* Without this we get recursive calls to #WM_exit_ex. */
|
||||
BPY_atexit_unregister();
|
||||
|
||||
Py_Finalize();
|
||||
|
||||
if (do_python_exit) {
|
||||
Py_Finalize();
|
||||
}
|
||||
(void)gilstate;
|
||||
#else
|
||||
PyGILState_Release(gilstate);
|
||||
(void)do_python_exit;
|
||||
#endif
|
||||
|
||||
#ifdef TIME_PY_RUN
|
||||
|
||||
@@ -34,13 +34,13 @@ static PyObject *bpy_atexit(PyObject * /*self*/, PyObject * /*args*/, PyObject *
|
||||
|
||||
bContext *C = BPY_context_get();
|
||||
/* As Python requested the exit, it handles shutting it's self down. */
|
||||
const bool do_python = false;
|
||||
const bool do_python_exit = false;
|
||||
/* User actions such as saving the session, preferences, recent-files for e.g.
|
||||
* should be skipped because an explicit call to exit is more likely to be used as part of
|
||||
* automated processes shouldn't impact the users session in the future. */
|
||||
const bool do_user_exit_actions = false;
|
||||
|
||||
WM_exit_ex(C, do_python, do_user_exit_actions);
|
||||
WM_exit_ex(C, do_python_exit, do_user_exit_actions);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
@@ -109,15 +109,14 @@ void WM_init(bContext *C, int argc, const char **argv);
|
||||
*
|
||||
* \param C: The context or null, a null context implies `do_user_exit_actions == false` &
|
||||
* prevents some editor-exit operations from running.
|
||||
* \param do_python: Free all data associated with Blender's Python integration.
|
||||
* Also exit the Python interpreter (unless `WITH_PYTHON_MODULE` is enabled).
|
||||
* \param do_python_exit: Exit the Python interpreter (unless `WITH_PYTHON_MODULE` is enabled).
|
||||
* \param do_user_exit_actions: When enabled perform actions associated with a user
|
||||
* having been using Blender then exiting. Actions such as writing the auto-save
|
||||
* and writing any changes to preferences.
|
||||
* Set to false in background mode or when exiting because of failed command line argument parsing.
|
||||
* In general automated actions where the user isn't making changes should pass in false too.
|
||||
*/
|
||||
void WM_exit_ex(bContext *C, bool do_python, bool do_user_exit_actions);
|
||||
void WM_exit_ex(bContext *C, bool do_python_exit, bool do_user_exit_actions);
|
||||
|
||||
/**
|
||||
* Main exit function to close Blender ordinarily.
|
||||
|
||||
@@ -490,7 +490,7 @@ void wm_exit_schedule_delayed(const bContext *C)
|
||||
|
||||
void UV_clipboard_free();
|
||||
|
||||
void WM_exit_ex(bContext *C, const bool do_python, const bool do_user_exit_actions)
|
||||
void WM_exit_ex(bContext *C, const bool do_python_exit, const bool do_user_exit_actions)
|
||||
{
|
||||
wmWindowManager *wm = C ? CTX_wm_manager(C) : nullptr;
|
||||
|
||||
@@ -663,8 +663,8 @@ void WM_exit_ex(bContext *C, const bool do_python, const bool do_user_exit_actio
|
||||
// free_txt_data();
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
/* option not to close python so we can use 'atexit' */
|
||||
if (do_python && ((C == nullptr) || CTX_py_init_get(C))) {
|
||||
/* Option not to exit Python so this function can called from 'atexit'. */
|
||||
if ((C == nullptr) || CTX_py_init_get(C)) {
|
||||
/* NOTE: (old note)
|
||||
* before BKE_blender_free so Python's garbage-collection happens while library still exists.
|
||||
* Needed at least for a rare crash that can happen in python-drivers.
|
||||
@@ -672,7 +672,7 @@ void WM_exit_ex(bContext *C, const bool do_python, const bool do_user_exit_actio
|
||||
* Update for Blender 2.5, move after #BKE_blender_free because Blender now holds references
|
||||
* to #PyObject's so #Py_DECREF'ing them after Python ends causes bad problems every time
|
||||
* the python-driver bug can be fixed if it happens again we can deal with it then. */
|
||||
BPY_python_end();
|
||||
BPY_python_end(do_python_exit);
|
||||
}
|
||||
#else
|
||||
(void)do_python;
|
||||
|
||||
Reference in New Issue
Block a user